Skip to content

[FEAT] add support for front matter #1149

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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/bootstrap@5.0.2/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/bootstrap@5.0.2/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/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/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
Loading