Extension for [Parsedown Extra](https://github.com/erusev/parsedown-extra) ========================================================================== > Configurable Markdown to HTML converter with Parsedown Extra. ![Parsedown Logo](https://user-images.githubusercontent.com/1669261/109982015-10e2c300-7d34-11eb-93bd-5f103b9d5165.png) Contents -------- - [Usage](#usage) - [Features](#features) - [Property Aliases as Methods](#property-aliases-as-methods) Usage ----- ### Manual Include `ParsedownExtraPlugin.php` just after the `Parsedown.php` and `ParsedownExtra.php` file: ~~~ .php require 'Parsedown.php'; require 'ParsedownExtra.php'; require 'ParsedownExtraPlugin.php'; # Create $Parsedown = new ParsedownExtraPlugin; # Configure $Parsedown->voidElementSuffix = '>'; // HTML5 # Use echo $Parsedown->text('# Header {.sth}'); ~~~ ### Composer From the file manager interface, create a `composer.json` file in your project folder, then add this content: ~~~ .json { "minimum-stability": "dev" } ~~~ From the command line interface, navigate to your project folder then run this command: ~~~ .sh composer require taufik-nurrohman/parsedown-extra-plugin ~~~ From the file manager interface, create an `index.php` file in your project folder then require the auto-loader file: ~~~ .php require 'vendor/autoload.php'; # Create $Parsedown = new ParsedownExtraPlugin; # Configure $Parsedown->voidElementSuffix = '>'; // HTML5 # Use echo $Parsedown->text('# Header {.sth}'); ~~~ Features -------- ### HTML or XHTML ~~~ .php $Parsedown->voidElementSuffix = '>'; // HTML5 ~~~ ### Predefined Abbreviations ~~~ .php $Parsedown->abbreviationData = [ 'CSS' => 'Cascading Style Sheet', 'HTML' => 'Hyper Text Markup Language', 'JS' => 'JavaScript' ]; ~~~ ### Predefined Reference Links and Images ~~~ .php $Parsedown->referenceData = [ 'mecha-cms' => [ 'url' => 'https://mecha-cms.com', 'title' => 'Mecha CMS' ], 'test-image' => [ 'url' => 'http://example.com/favicon.ico', 'title' => 'Test Image' ] ); ~~~ ### Automatic `rel="nofollow"` Attribute on External Links ~~~ .php $Parsedown->linkAttributes = function($Text, $Attributes, &$Element, $Internal) { if (!$Internal) { return [ 'rel' => 'nofollow', 'target' => '_blank'; ]; } return []; }; ~~~ ### Automatic `id` Attribute on Headers ~~~ .php $Parsedown->headerAttributes = function($Text, $Attributes, &$Element, $Level) { $Id = $Attributes['id'] ?? trim(preg_replace('/[^a-z\d\x{4e00}-\x{9fa5}]+/u', '-', strtolower($Text)), '-'); return ['id' => $Id]; }; ~~~ ### Automatic Figure Elements Every image markup that appears alone in a paragraph will be converted into a figure element automatically. ~~~ .php $Parsedown->figuresEnabled = true; $Parsedown->figureAttributes = ['class' => 'image']; $Parsedown->imageAttributesOnParent = ['class', 'id']; ~~~ To add a caption below the image, prepend at least one space but less than four spaces to turn the paragraph sequence that comes after the image into an image caption. ~~~ .markdown This is a paragraph. ![Image](/path/to/image.jpg) Image caption. This is a paragraph. ![Image](/path/to/image.jpg) Image caption in a paragraph tag. This is a paragraph. ![Image](/path/to/image.jpg) This is a code block. This is a paragraph. ~~~ FYI, this format is also valid for average Markdown files. And so, it will degraded gracefully when parsed by other Markdown converters. ### Custom Code Block Class Format ~~~ .php $Parsedown->blockCodeClassFormat = 'language-%s'; ~~~ ### Custom Code Block Contents ~~~ .php $Parsedown->codeHtml = '%s'; $Parsedown->blockCodeHtml = '%s'; ~~~ ~~~ .php // function doApplyHighlighter(string $Text, array $ClassList, &$Element) { $Highlight = new \Highlight\Highlighter; $Highlight->setAutodetectLanguages($ClassList); $Highlighted = $Highlight->highlightAuto($Text); $Element['attributes']['class'] = 'hljs ' . $Highlighted->language; return $Highlighted->value; } $Parsedown->codeHtml = function($Text, $Attributes, &$Element) { return doApplyHighlighter($Text, [], $Element); }; $Parsedown->blockCodeHtml = function($Text, $Attributes, &$Element) { $ClassList = array_filter(explode(' ', $Attributes['class'] ?? "")); return doApplyHighlighter($Text, $ClassList, $Element); }; ~~~ ### Put `` Attributes on `
` Element

~~~ .php
$Parsedown->codeAttributesOnParent = true;
~~~

### Custom Quote Block Class

~~~ .php
$Parsedown->blockQuoteAttributes = ['class' => 'quote'];
~~~

~~~ .php
$Parsedown->blockQuoteAttributes = function($Text, $Attributes, &$Element) {
    if (strpos($Text, '**Danger:** ') === 0) {
        return ['class' => 'alert alert-danger'];
    }
    if (strpos($Text, '**Info:** ') === 0) {
        return ['class' => 'alert alert-info'];
    }
    return [];
};
~~~

### Custom Table Attributes

~~~ .php
$Parsedown->tableAttributes = ['border' => 1];
~~~

### Custom Table Alignment Class

~~~ .php
$Parsedown->tableColumnAttributes = function($Text, $Attributes, &$Element, $Align) {
    return [
        'class' => $Align ? 'text-' . $Align : null,
        'style' => null // Remove inline styles
    ];
};
~~~

### Custom Footnote ID Format

~~~ .php
$Parsedown->footnoteLinkAttributes = function($Number, $Attributes, &$Element, $Name) {
    return ['href' => '#to:' . $Name];
};

$Parsedown->footnoteReferenceAttributes = function($Number, $Attributes, &$Element, $Name, $Index) {
    return ['id' => 'from:' . $Name . '.' . $Index];
};

$Parsedown->footnoteBackLinkAttributes = function($Number, $Attributes, &$Element, $Name, $Index) {
    return ['href' => '#from:' . $Name . '.' . $Index];
};

$Parsedown->footnoteBackReferenceAttributes = function($Number, $Attributes, &$Element, $Name, $Total) {
    return ['id' => 'to:' . $Name];
};
~~~

### Custom Footnote Class

~~~ .php
$Parsedown->footnoteAttributes = ['class' => 'notes'];
~~~

### Custom Footnote Link Text

~~~ .php
$Parsedown->footnoteLinkHtml = '[%s]';
~~~

### Custom Footnote Back Link Text

~~~ .php
$Parsedown->footnoteBackLinkHtml = '';
~~~

### Advance Attribute Parser

 - `{#foo}` → ``
 - `{#foo#bar}` → ``
 - `{.foo}` → ``
 - `{.foo.bar}` → ``
 - `{#foo.bar.baz}` → ``
 - `{#foo .bar .baz}` → `` (white-space before `#` and `.` becomes optional in my extension)
 - `{foo="bar"}` → ``
 - `{foo="bar baz"}` → ``
 - `{foo='bar'}` → ``
 - `{foo='bar baz'}` → ``
 - `{foo=bar}` → ``
 - `{foo=}` → ``
 - `{foo}` → ``
 - `{foo=bar baz}` → ``
 - `{#a#b.c.d e="f" g="h i" j='k' l='m n' o=p q= r s t="u#v.w.x y=z"}` → ``

### Code Block Class Without `language-` Prefix

Dot prefix in class name are now becomes optional, custom attributes syntax also acceptable:

 - `php` → `
`
 - `php html` → `
`
 - `.php` → `
`
 - `.php.html` → `
`
 - `.php html` → `
`
 - `{.php #foo}` → `
`


Property Aliases as Methods
---------------------------

Property aliases are available as methods just to follow the way **Parsedown** set its configuration data. It uses PHP `__call` method to generate the class methods automatically:

~~~ .php
// This is ...
$Parsedown->setBlockCodeHtml(function() { ... });

// ... equal to this
$Parsedown->blockCodeHtml = function() { ... };
~~~