Skip to content

Commit

Permalink
Merge pull request #1149 from phpDocumentor/feature/front-matter
Browse files Browse the repository at this point in the history
[FEAT] add support for front matter
  • Loading branch information
jaapio authored Oct 23, 2024
2 parents 51bae55 + 3f55613 commit e68d1c4
Show file tree
Hide file tree
Showing 12 changed files with 341 additions and 3 deletions.
77 changes: 75 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/guides-markdown/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"require": {
"php": "^8.1",
"league/commonmark": "^2.4",
"phpdocumentor/guides": "^1.0 || ^2.0"
"phpdocumentor/guides": "^1.0 || ^2.0",
"symfony/yaml": "^6.4 || ^7.0"
},
"extra": {
"branch-alias": {
Expand Down
9 changes: 9 additions & 0 deletions packages/guides-markdown/resources/config/guides-markdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use phpDocumentor\Guides\Markdown\MarkupLanguageParser;
use phpDocumentor\Guides\Markdown\Parsers\BlockQuoteParser;
use phpDocumentor\Guides\Markdown\Parsers\CodeBlockParser;
use phpDocumentor\Guides\Markdown\Parsers\FrontMatter\TitleParser;
use phpDocumentor\Guides\Markdown\Parsers\FrontMatterParser;
use phpDocumentor\Guides\Markdown\Parsers\HeaderParser;
use phpDocumentor\Guides\Markdown\Parsers\HtmlParser;
use phpDocumentor\Guides\Markdown\Parsers\InlineParsers\EmphasisParser;
Expand Down Expand Up @@ -82,6 +84,13 @@
->set(NewLineParser::class)
->tag('phpdoc.guides.markdown.parser.inlineParser')

->set(FrontMatterParser::class)
->arg('$fieldParsers', tagged_iterator('phpdoc.guides.markdown.front_matter', 'fieldName'))
->tag('phpdoc.guides.markdown.parser.blockParser')

->set(TitleParser::class)
->tag('phpdoc.guides.markdown.front_matter')

->set(MarkupLanguageParser::class)
->arg('$parsers', tagged_iterator('phpdoc.guides.markdown.parser.blockParser'))
->tag('phpdoc.guides.parser.markupLanguageParser');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
use League\CommonMark\Environment\Environment as CommonMarkEnvironment;
use League\CommonMark\Extension\Autolink\AutolinkExtension;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\FrontMatter\Data\SymfonyYamlFrontMatterParser;
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
use League\CommonMark\Extension\Table\TableExtension;
use League\CommonMark\Node\Block\Document;
use League\CommonMark\Node\NodeWalker;
Expand Down Expand Up @@ -54,6 +56,7 @@ public function __construct(
$cmEnvironment->addExtension(new CommonMarkCoreExtension());
$cmEnvironment->addExtension(new TableExtension());
$cmEnvironment->addExtension(new AutolinkExtension());
$cmEnvironment->addExtension(new FrontMatterExtension(new SymfonyYamlFrontMatterParser()));
$this->markdownParser = new MarkdownParser($cmEnvironment);
// if for backward compatibility reasons no settings manager was passed, use the defaults
$this->settingsManager = $settingsManager ?? new SettingsManager(new ProjectSettings());
Expand Down
20 changes: 20 additions & 0 deletions packages/guides-markdown/src/Markdown/NullNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Guides\Markdown;

use phpDocumentor\Guides\Nodes\TextNode;

final class NullNode extends TextNode
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Guides\Markdown\Parsers\FrontMatter;

use phpDocumentor\Guides\Nodes\DocumentNode;
use phpDocumentor\Guides\Nodes\Inline\PlainTextInlineNode;
use phpDocumentor\Guides\Nodes\Metadata\AuthorNode;

final class AuthorParser implements Parser
{
/** {@inheritDoc} */
public function process(DocumentNode $document, mixed $value, array $frontMatter): void
{
$value = '' . $value;
$document->addHeaderNode(new AuthorNode($value, [new PlainTextInlineNode($value)]));
}

public function field(): string
{
return 'title';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Guides\Markdown\Parsers\FrontMatter;

use phpDocumentor\Guides\Nodes\DocumentNode;

interface Parser
{
public function field(): string;

/** @param array<string, mixed> $frontMatter */
public function process(DocumentNode $document, mixed $value, array $frontMatter): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Guides\Markdown\Parsers\FrontMatter;

use phpDocumentor\Guides\Nodes\DocumentNode;

final class TitleParser implements Parser
{
/** {@inheritDoc} */
public function process(DocumentNode $document, mixed $value, array $frontMatter): void
{
$document->setMetaTitle('' . $value);
}

public function field(): string
{
return 'title';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Guides\Markdown\Parsers;

use League\CommonMark\Node\Block\Document;
use League\CommonMark\Node\Node as CommonMarkNode;
use League\CommonMark\Node\NodeWalker;
use League\CommonMark\Node\NodeWalkerEvent;
use phpDocumentor\Guides\Markdown\NullNode;
use phpDocumentor\Guides\Markdown\ParserInterface;
use phpDocumentor\Guides\Markdown\Parsers\FrontMatter\Parser as FieldParser;
use phpDocumentor\Guides\MarkupLanguageParser as GuidesParser;
use phpDocumentor\Guides\Nodes\Node;

use function array_key_exists;
use function is_array;

/** @implements ParserInterface<NullNode> */
final class FrontMatterParser implements ParserInterface
{
/** @var array<string, FieldParser> */
private array $fieldParsers;

/** @param iterable<string, FieldParser> $fieldParsers */
public function __construct(iterable $fieldParsers)
{
foreach ($fieldParsers as $parser) {
$this->fieldParsers[$parser->field()] = $parser;
}
}

public function parse(GuidesParser $parser, NodeWalker $walker, CommonMarkNode $current): Node
{
$frontMatter = $current->data->get('front_matter', []);
if (is_array($frontMatter) === false) {
return new NullNode('');
}

foreach ($frontMatter as $field => $value) {
if (!array_key_exists($field, $this->fieldParsers)) {
continue;
}

$this->fieldParsers[$field]->process($parser->getDocument(), $value, $frontMatter);
}

return new NullNode('');
}

public function supports(NodeWalkerEvent $event): bool
{
return $event->getNode() instanceof Document;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
<title>Front Matter</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<header class="">
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
</ul>
</div>
</div>
</nav>
</header>
<main id="main-content">
<div class="container">
<div class="container">
<div class="row">
<div class="col-lg-3">
<nav class="nav flex-column">
<ul class="menu-level-main">
</ul>
</nav>
</div>
<div class="col-lg-9">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Document Title</a></li>
</ol>
</nav>
<!-- content start -->
<div class="section" id="document-title">
<h1>Document Title</h1>
<p>Lorem Ipsum Dolor.</p>
</div>
<!-- content end -->
</div>
</div>
</div>
</div>
</main>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<!-- Option 2: Separate Popper and Bootstrap JS -->
<!--
<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
-->
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<guides xmlns="https://www.phpdoc.org/guides"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.phpdoc.org/guides packages/guides-cli/resources/schema/guides.xsd"
theme="bootstrap"
input-format="md"
links-are-relative="1"
automatic-menu="true"
>
<extension class="phpDocumentor\Guides\Bootstrap"/>
</guides>
Loading

0 comments on commit e68d1c4

Please sign in to comment.