devster / frontmatter
A php `frontmatter` parser
Requires
- php: >=5.3.0
- symfony/property-access: ~2.6
Requires (Dev)
- erusev/parsedown-extra: ~0.7
- phpunit/phpunit: ~4.5
- scrutinizer/ocular: ~1.1
- seld/jsonlint: ~1.3
- symfony/yaml: ~2.6
Suggests
- erusev/parsedown-extra: Allows you to use built-in Markdown parser
- seld/jsonlint: Allows you to use built-in JSON parser
- symfony/yaml: Allows you to use built-in YAML parser
This package is auto-updated.
Last update: 2024-10-29 01:27:14 UTC
README
[WIP] Frontmatter Jekyll style parser
Available parsers:
- yaml (use symfony/yaml)
- Markdown (use erusev/parsedown-extra)
- Json (use seld/jsonlint)
Install
Via Composer
$ composer require devster/frontmatter
And add extra packages that built-in parsers use:
# YAML $ composer require symfony/yaml # Markdown $ composer require erusev/parsedown-extra # Json $ composer require seld/jsonlint
These packages are not required by default to minimize the footprint and speed up your install if you only need few of them
Usage
Basic usage
require '../vendor/autoload.php'; $parser = new Devster\Frontmatter\Parser('yaml', 'markdown'); $content = <<<EOF --- title: My Content description: "This is a description" --- This is *Markdown* content EOF; $frontmatter = $parser->parse($content); echo $frontmatter->head['title']; // My content echo $frontmatter->getBody(); // This is <em>Markdown</em> content
And because the frontmatter format is not only used by developers, this parser is quite permissive
All content examples above are parsed like normal frontmatter content:
$content = <<<EOF --- title: My Title --- # Title 1 ## Title 2 EOF; $content = <<<EOF --- title: My Title --- # Title 1 ## Title 2 EOF;
Just parse frontmatter, and don't process head and body
$p = new Parser; $result = $p->parseFrontmatter($content); echo $result['head']; echo $result['body'];
Customize the frontmatter delimiter
$p = new Parser('json', 'markdown', '##'); $p->parse(<<<EOF ## { "title": "My title" } ## Body content EOF); // You can also let your user use its own delimiter $p = new Parser; $p ->guessDelimiter() ->parse(<<<EOF ~~X~~ head ~~X~~ body EOF);
Guess parsers from filename
The frontmatter parsers can be guessed from a filename, based on the extensions.
Take a look at these examples below:
my_file.json.md
: Head in Json and Body in Markdownmy_file.md
: Head will be parse with the parser set in the constructor, Body in Markdownmy_file.unknown
: An exception will be thrownmy_file.yml.unknown
: An exception will be thrown
$p = new Parser; $p ->guessParsersFromFilename('my_file.yml.md') ->parse(file_gets_content('my_file.yml.md')) ; // Or you can set the default head parser $p = new Parser('json'); $p ->guessParsersFromFilename('my_file.md') ->parse(file_gets_content('my_file.md')) ;
Guess body parser from head
You can also define explicitly in the head which parser the body should be parsed with.
$p = new Parser('yaml'); $p ->guessBodyParserFromHead('[options][format]') ->parse(<<<EOF --- title: My Title options: format: json --- { "body": "This is my body" } EOF);
Internally the Property Access Component from symfony is used. Refer to its documentation to find the path that will be used to grab the parser from the head
If the parser could not be fetch from the head, the default body parser will be use.
More complex usage
$p = new Devster\Frontmatter\Parser('yml', 'md'); $p ->guessDelimiter() ->guessParsersFromFilename('my_file.md') ->guessBodyParserFromHead('[format]') ; try { $p->parse($content); } catch (Devster\Frontmatter\Exception\Exception $e) { if ($e instanceof Devster\Frontmatter\Exception\ParserNotFoundException) { // The head or the body parser is not found } if ($e instanceof Devster\Frontmatter\Exception\ParsingException) { // Unable to parse the frontmatter content // or // an error occured in head or body parsing } }
Testing
$ vendor/bin/phpunit
Roadmap
- Rename head to header
- Add an INI parser
- Allow to not parse the body to avoid the creation of a new custom parser if the need is not built-in
- Add a validate feature
- Add dumping feature
Contributing
Please see CONTRIBUTING for details.
Credits
Special thank to Etienne Zannelli for his help on Regex ❤
License
The MIT License (MIT). Please see License File for more information.