Skip to content

Commit

Permalink
[FEAT] add support for front matter
Browse files Browse the repository at this point in the history
Front matter format allows us to add extra meta data to documents
like we can with fields in RST. This is a first setup that demos
the way we can implement extra fields.
  • Loading branch information
jaapio committed Oct 22, 2024
1 parent 51bae55 commit 3f55613
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 3f55613

Please sign in to comment.