/smolblog-markdown

A superset of Markdown with some Smolblog flair.

Primary LanguagePHPBSD 3-Clause "New" or "Revised" LicenseBSD-3-Clause

Smolblog-flavored Markdown

A superset of Markdown with some Smolblog flair.

Why?

Picking a Markdown dialect to support is a contract with your users. And while I would love to support every flavor of Markdown possible, it is more valuable, especially in these early days, to start small and expand from there.

Thus, instead of picking Github Flavored Markdown or even the proposed CommonMark standard, we are instead supporting the John Gruber/Aaron Swartz original flavor with a limited number of add-ons and original extensions.

And also because it's cool.

Original Extensions

oEmbed

Being able to embed content from around the internet is core to Smolblog's philosophy, so being able to add embedded content to a post is certainly important. The embed extension tells the parser to attempt to embed the given URL using oEmbed.

While this is similar to images, both in syntax and execution, it is not deterministic. The same image Markdown code will always generate the same HTML code. This is not true for oEmbed as the final HTML code is decided by a remote server in most cases. An image does not have to exist when the Markdown is converted to HTML, but the remote webpage does need to exist in order to get the code to embed it. A well-crafted library could mitigate this concern. Regardless, if the parser does not get an oEmbed code, it will default back to a standard link.

Thanks to Chris and Logan for chiming in on Micro.blog about this.

The markdown:

:[An innocuous YouTube video](https://youtu.be/rTga41r3a4s)

The markup:

<iframe width="200" height="113" src="https://www.youtube.com/embed/rTga41r3a4s?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Rick Astley - Never Gonna Give You Up (Pianoforte) (Performance)"></iframe>

The markup (without oEmbed)

<p><a href="https://youtu.be/rTga41r3a4s" target="_blank">An innocuous YouTube video</a></p>

Other add-ons

These are attributes and extensions found in other dialects of Markdown that we are choosing to support.

Fenced code blocks

These are most commonly seen in developer documentation, but as tutorials and examples can be key parts of many developers' blogs, this felt like a good add-on to consider. Its syntax is unobtrusive, and it adds an explicit tag for the programming language being used, if any.

Note that the original code block of a single tab or 4 spaces is still supported (and in fact used here).

The markdown:

```php
$extArray = json_decode($results['extensions'] ?? '{}', associative: true);
$extParsed = [];
foreach ($extArray as $class => $data) {
	$extParsed[$class] = $class::fromArray($data);
}
```

The markup:

<pre><code class="language-php">$extArray = json_decode($results['extensions'] ?? '{}', associative: true);
$extParsed = [];
foreach ($extArray as $class => $data) {
	$extParsed[$class] = $class::fromArray($data);
}
</code></pre>

(Actually bringing in syntax highlighting is a problem for future Smolblog.)

Using this library

Install it using composer: composer require smolblog/smolblog-markdown not on packagist yet ^^;;_

Create a parser without oEmbed

use Smolblog\Markdown\SmolblogMarkdown;

//...

$md = new SmolblogMarkdown();

This will create the parser with no oEmbed support. Embed directives will show as normal links as seen above.

Create a parser with oEmbed

You will need the Embed library installed (run composer require embed/embed). Support for other libraries coming soon!

use Smolblog\Markdown\{SmolblogMarkdown, DefaultEmbedProvider};

//...

$md = new SmolblogMarkdown(embedProvider: new DefaultEmbedProvider());

Custom oEmbed provider

If you have a different oEmbed library you want to use, you can pass in anything that implements the EmbedProvider interface:

interface EmbedProvider {
	public function getEmbedCodeFor(string $url): ?string;
}

Parsing Markdown

Once you have the parser instantiated, it's as easy as:

$md->parse($markdown_text);

This library is built on cebe/markdown, and more detailed usage can be found in its documentation.

Acknowledgements

  • Based on cebe/markdown
  • Syntax feedback provided by Chris and Logan
  • Built by Evan Hildreth for the Smolblog project