diff --git a/composer.json b/composer.json index 0425862..fa3e2ac 100644 --- a/composer.json +++ b/composer.json @@ -13,14 +13,15 @@ ], "bin": ["bin/daux"], "require": { - "php": ">=5.5", - "league/plates": "~3.1", "guzzlehttp/guzzle": "~6.0", "league/commonmark": "^0.13", + "league/plates": "~3.1", + "myclabs/deep-copy": "^1.5", + "php": ">=5.5", "symfony/console": "~3.0", "symfony/finder": "~3.0", "webuni/commonmark-table-extension": "0.4.*", - "myclabs/deep-copy": "^1.5" + "webuni/front-matter": "^0.2.0" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 249034d..428daf4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "d8c4d9d882622af07b8a8a0fad47a353", - "content-hash": "b0946ce60712726d3e60655d461db484", + "hash": "3f12815cfe3d8c82016da7a7a12021a0", + "content-hash": "746afc5f583eddb95134fae836cd66f3", "packages": [ { "name": "guzzlehttp/guzzle", @@ -558,6 +558,55 @@ ], "time": "2016-05-18 14:26:46" }, + { + "name": "symfony/yaml", + "version": "v3.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/2884c26ce4c1d61aebf423a8b912950fe7c764de", + "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2016-06-29 05:41:56" + }, { "name": "webuni/commonmark-table-extension", "version": "0.4.3", @@ -611,6 +660,62 @@ "table" ], "time": "2016-01-14 22:54:18" + }, + { + "name": "webuni/front-matter", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/webuni/front-matter.git", + "reference": "dfede21e98a91729151e9665a81215f838e9320f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webuni/front-matter/zipball/dfede21e98a91729151e9665a81215f838e9320f", + "reference": "dfede21e98a91729151e9665a81215f838e9320f", + "shasum": "" + }, + "require": { + "php": "^5.5|^7.0", + "symfony/yaml": "^2.3|^3.0" + }, + "require-dev": { + "coduo/phpspec-data-provider-extension": "^1.0", + "fabpot/php-cs-fixer": "^1.9", + "memio/spec-gen": "~0.3", + "mthaml/mthaml": "^1.2", + "phpspec/phpspec": "^2.5", + "twig/twig": "~1.20|~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "autoload": { + "psr-4": { + "Webuni\\FrontMatter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Martin HasoĊˆ", + "email": "martin.hason@gmail.com", + "role": "Lead Developer" + } + ], + "description": "Front matter parser and dumper for PHP", + "homepage": "https://github.com/webuni/front-yaml", + "keywords": [ + "front-matter", + "yaml" + ], + "time": "2016-04-26 23:39:13" } ], "packages-dev": [ @@ -1665,55 +1770,6 @@ "homepage": "https://github.com/sebastianbergmann/version", "time": "2015-06-21 13:59:46" }, - { - "name": "symfony/yaml", - "version": "v3.1.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/2884c26ce4c1d61aebf423a8b912950fe7c764de", - "reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2016-06-29 05:41:56" - }, { "name": "webmozart/assert", "version": "1.0.2", diff --git a/docs/01_Features/Front_Matter.md b/docs/01_Features/Front_Matter.md new file mode 100644 index 0000000..b38e10a --- /dev/null +++ b/docs/01_Features/Front_Matter.md @@ -0,0 +1,18 @@ +To customize your pages even further, you can add a Front Matter to your files. + +Front Matter is a block you add at the top of your file and looks like this: + + --- + title: Hallo Welt + date: 12th December 1984 + --- + +## Changing the title + +The only implemented customization right now is the override of the title. + +If your file is named "Hello_World_de.md" and your front matter is the one displayed above, you will get a page named "Hallo Welt" + +## For Developers + +You can then access this information in each `Content` with `$content->getAttributes()` diff --git a/docs/02_Examples/Hello_World_de.md b/docs/02_Examples/Hello_World_de.md index 6b02b2e..96304e2 100644 --- a/docs/02_Examples/Hello_World_de.md +++ b/docs/02_Examples/Hello_World_de.md @@ -1,5 +1,6 @@ +--- title: Hallo Welt date: 12th December 1984 -------- +--- This is a page which has attributes and a overriden Title diff --git a/libs/Tree/Content.php b/libs/Tree/Content.php index c81a85c..f40e303 100644 --- a/libs/Tree/Content.php +++ b/libs/Tree/Content.php @@ -1,5 +1,7 @@ attributes = []; - $content = $this->getContent(); - $sections = preg_split('/\s+-{3,}\s+/', $content, 2); + $frontMatter = new FrontMatter(); - // Only do it if we have two sections - if (count($sections) != 2) { - return; - } + $document = $frontMatter->parse($this->getContent()); - // Parse the different attributes - $lines = preg_split('/\n/', $sections[0]); - foreach ($lines as $line) { - $trimmed = trim($line); - if ($trimmed == '') { - continue; - } // skip empty lines - if ($trimmed[0] == '#') { - continue; - } // can be taken as comments - - $re = '/^([-\\w]*)\\s*?:(.*)/'; - if (!preg_match($re, $trimmed, $parts)) { - break; - } //Break as soon as we have a line that doesn't match - - $key = strtolower(trim($parts[1])); - $value = trim($parts[2]); - $this->attributes[$key] = $value; - } - - // Only remove the content if we have at least one attribute - if (count($this->attributes) > 0) { - $this->setContent($sections[1]); - } + $this->attributes = array_replace_recursive($this->attributes, $document->getData()); + $this->setContent($document->getContent()); } public function setAttributes(array $attributes) diff --git a/test.php b/test.php new file mode 100644 index 0000000..e69de29 diff --git a/tests/Tree/ContentTest.php b/tests/Tree/ContentTest.php index c42608c..b91b2e7 100644 --- a/tests/Tree/ContentTest.php +++ b/tests/Tree/ContentTest.php @@ -20,11 +20,10 @@ class ContentTest extends \PHPUnit_Framework_TestCase { return [ ['This is content', [], 'This is content'], - ["title: This is a simple title\n---\nThis is content\n", ['title' => 'This is a simple title'], 'This is content'], - ["title: This is a simple title\ntitle :This is another title\n---\nThis is content\n", ['title' => 'This is another title'], 'This is content'], - ["title: This is a simple title\nthis is not metadata\n---\nThis is content\n", ['title' => 'This is a simple title'], 'This is content'], + ["---\ntitle: This is a simple title\n---\nThis is content\n", ['title' => 'This is a simple title'], 'This is content'], + ["---\ntitle: This is a simple title\ntags:\n - One\n - Second Tag\n---\nThis is content\n", ['title' => 'This is a simple title', 'tags' => ['One', 'Second Tag']], 'This is content'], ['title: This is only metatada, no content', [], 'title: This is only metatada, no content'], - ["title: This is almost only metadata\n---\n", ['title' => 'This is almost only metadata'], ''], + ["---\ntitle: This is almost only metadata\n---\n", ['title' => 'This is almost only metadata'], ''], ["# Some content\n\nhi\n```yml\nvalue: true\n```\n----\n Follow up", [], "# Some content\n\nhi\n```yml\nvalue: true\n```\n----\n Follow up"], ]; } @@ -42,7 +41,7 @@ class ContentTest extends \PHPUnit_Framework_TestCase public function testNoAttributes() { - $content = "This is a content with a separator\n----\n this wasn't an attribute"; + $content = "This is a content with a separator\n---\n this wasn't an attribute"; $obj = $this->createContent($content); @@ -51,8 +50,8 @@ class ContentTest extends \PHPUnit_Framework_TestCase public function testContentPreserved() { - $content = "this was an attribute, but also a separator\n----\nand it works"; - $with_attribute = "title: a title\n----\n$content"; + $content = "this was an attribute, but also a separator\n---\nand it works"; + $with_attribute = "---\ntitle: a title\n---\n$content"; $obj = $this->createContent($with_attribute);