From 821ea0df1625f1355f65914d54c01954cb16e3c6 Mon Sep 17 00:00:00 2001 From: Dendy Faist Date: Mon, 14 Apr 2025 04:22:07 +0200 Subject: [PATCH] feat: Implement parsing of PANDOC-style YAML metadata --- src/Controller/MainController.php | 35 ++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Controller/MainController.php b/src/Controller/MainController.php index fe2dc79..3da9a49 100644 --- a/src/Controller/MainController.php +++ b/src/Controller/MainController.php @@ -9,6 +9,7 @@ use Symfony\Component\Finder\Finder; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Process\Process; use Symfony\Component\Routing\Attribute\Route; +use Symfony\Component\Yaml\Yaml; final class MainController extends AbstractController { @@ -46,6 +47,10 @@ final class MainController extends AbstractController $fs = new Filesystem(); $contents = $fs->exists($fullPath) ? $fs->readFile($fullPath) : null; + [ + 'data' => $metadata, + 'text' => $text + ] = $this->extractMetadata($contents); // -------------------------------------------------- Get data tree --- @@ -74,9 +79,37 @@ final class MainController extends AbstractController return $this->render('main/index.html.twig', [ 'path' => $path, - 'contents' => $contents, + 'contents' => $text, + 'metadata' => $metadata, 'tree' => $tree, 'version' => (new Process(['git', '-C', $gitDir, 'log', '-1', '--oneline']))->mustRun()->getOutput(), ]); } + + /** + * Parses all YAML metadata blocks in a given string and returns the text + * without such blocks. + */ + private function extractMetadata(?string $text): array + { + if ($text === null) return ['data' => null, 'text' => null]; + + $start = strpos($text, "---\n"); + $end = strpos($text, "...\n", $start) ?: strpos($text, "---\n", $start + 4); + + // No more moteadata, return as is. Recursion stop condition + if ($start === false or $end === false) { + return ['text' => $text, 'data' => []]; + } + + $yaml = Yaml::parse(substr($text, $start + 4, $end - $start - 4)); + $rest = substr($text, 0, $start) . substr($text, $end + 4); + + // Recurse until there's no more metadata blocks, overwriting as we go + $nextIteration = $this->extractMetadata($rest); + return [ + 'data' => $nextIteration['data'] + $yaml, + 'text' => $nextIteration['text'], + ]; + } }