From c8e239672d82a7757d7c61535ad66b33de68aec6 Mon Sep 17 00:00:00 2001 From: tabuna Date: Fri, 10 Nov 2023 05:41:37 +0300 Subject: [PATCH] Change docs formating for views --- app/Docs.php | 10 +- app/Http/Controllers/DocsController.php | 10 +- app/View/Components/Docs/Anchors.php | 83 ++++++++++ app/View/Components/Docs/Content.php | 146 +++++++++++++++++ composer.json | 8 +- composer.lock | 189 ++++++++++++++++++++++- resources/views/pages/docs.blade.php | 47 ++++-- resources/views/particles/docs.blade.php | 1 - 8 files changed, 463 insertions(+), 31 deletions(-) create mode 100644 app/View/Components/Docs/Anchors.php create mode 100644 app/View/Components/Docs/Content.php delete mode 100644 resources/views/particles/docs.blade.php diff --git a/app/Docs.php b/app/Docs.php index 851dce87..7c55334a 100644 --- a/app/Docs.php +++ b/app/Docs.php @@ -22,6 +22,8 @@ class Docs */ public const SUPPORT_VERSION = [ '8.x', + '5.4', + '4.2' ]; /** @@ -93,13 +95,12 @@ public function view(string $view) { $content = Str::of($this->page) ->replace('{{version}}', $this->version) - ->replace('{note}','⚠️') - ->replace('{tip}','💡️') ->after('---') ->after('---') ->markdown(); $all = collect()->merge($this->variables)->merge([ + 'docs' => $this, 'content' => $content, 'edit' => $this->goToGitHub(), ]); @@ -120,7 +121,8 @@ public function getMenu(): array ->after('---') ->after('---') ->replace('{{version}}', $this->version) - ->markdown()->toString(); + ->markdown() + ->toString(); return $this->docsToArray($html); } @@ -197,7 +199,7 @@ static public function every(string $version): \Illuminate\Support\Collection */ public function fetchBehind(): int { - throw_unless(isset($this->variables['git']), new Exception("Document {$this->path} does not have a git hash")); + throw_unless(isset($this->variables['git']), new Exception("The document {$this->path} is missing a Git hash")); $response = Http::withBasicAuth('token', config('services.github.token')) ->get("https://api.github.com/repos/laravel/docs/commits?sha={$this->version}&path={$this->file}"); diff --git a/app/Http/Controllers/DocsController.php b/app/Http/Controllers/DocsController.php index a17de002..e43754ba 100644 --- a/app/Http/Controllers/DocsController.php +++ b/app/Http/Controllers/DocsController.php @@ -4,7 +4,6 @@ use App\Docs; use App\Models\Document; -use Illuminate\Http\Request; class DocsController extends Controller { @@ -14,19 +13,14 @@ class DocsController extends Controller * @param string $version * @param string $page * - * @return \Illuminate\View\View + * @return \Illuminate\View\View| * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException */ public function show(string $version = Docs::DEFAULT_VERSION, string $page = 'installation') { $docs = new Docs($version, $page); - $text = $docs->view('particles.docs'); - - return view('pages.docs', [ - 'docs' => $docs, - 'text' => $text, - ]); + return $docs->view('pages.docs'); } /** diff --git a/app/View/Components/Docs/Anchors.php b/app/View/Components/Docs/Anchors.php new file mode 100644 index 00000000..9af215df --- /dev/null +++ b/app/View/Components/Docs/Anchors.php @@ -0,0 +1,83 @@ +content = $content; + } + + /** + * Get the view / contents that represent the component. + * + * @return \Illuminate\Contracts\View\View|\Closure|string + * @throws \DOMException + */ + public function render() + { + return view('components.docs.anchors', [ + 'anchors' => $this->findAnchors(), + ]); + } + + + /** + * @param $contents + * + * @return array + * @throws \DOMException + */ + private function findAnchors() + { + $crawler = new Crawler(); + $crawler->addContent(mb_convert_encoding($this->content, "UTF-8")); + + $anchors = []; + + $crawler + ->filter('h2,h3') + ->each(function ($elm) use (&$anchors) { + + /** @var Crawler $elm */ + /** @var \DOMElement $node */ + $node = $elm->getNode(0); + $text = $node->textContent; + $id = Str::slug($text); + + + $anchors[] = [ + 'text' => $text, + 'level' => $node->tagName, + 'id' => $id, + ]; + + while ($node->hasChildNodes()) { + $node->removeChild($node->firstChild); + } + + + $node->appendChild(new \DOMElement('a', e($text))); + $node->firstChild->setAttribute('href', '#' . $id); + $node->firstChild->setAttribute('name', $id); + }); + + return $anchors; + } + +} diff --git a/app/View/Components/Docs/Content.php b/app/View/Components/Docs/Content.php new file mode 100644 index 00000000..60631273 --- /dev/null +++ b/app/View/Components/Docs/Content.php @@ -0,0 +1,146 @@ +content = $content; + } + + /** + * Get the view / contents that represent the component. + * + * @return \App\View\Components\DocsContent + * @throws \DOMException + */ + public function render() + { + return $this; + } + + /** + * @param $contents + * + * @return string + * @throws \DOMException + */ + private function modifyContent() + { + $crawler = new Crawler(); + $crawler->addHtmlContent( mb_convert_encoding($this->content, "UTF-8")); + $this->content = $crawler->filterXpath('//body')->first()->html(); + + + $crawler->filter('blockquote')->each(function (Crawler $elm) { + $tag = $elm->outerHtml(); + + $html = $tag; + + if(Str::of($tag)->contains('{note}')){ + $html = Str::of($tag) + ->replace('
', '
') + ->replace('{note}', ''); + } + + if(Str::of($tag)->contains('{tip}')){ + $html = Str::of($tag) + ->replace('
', '
') + ->replace('{tip}', ''); + } + + $this->content = Str::of($this->content)->replace($tag, $html); + }); + + $crawler->filter('x-docs-banner')->each(function (Crawler $elm) { + $tag = $elm->outerHtml(); + + $this->content = Str::of($this->content) + ->replace($tag, Blade::render($tag)); + }); + + + $crawler->filter('h1')->each(function (Crawler $elm) { + $tag = $elm->outerHtml(); + + $this->content = Str::of($this->content)->replace($tag, ''); + }); + + $crawler + ->filter('h2,h3,h4,h5,h6') + ->each(function (Crawler $elm) use (&$anchors) { + + /** @var \DOMElement $node */ + $node = $elm->getNode(0); + + $content = $node->textContent; + $id = Str::slug($content); + $tag = $node->nodeName; + + $this->content = Str::of($this->content) + ->replace($elm->outerHtml(), "<$tag>$content"); + }); + + $crawler + ->filter('img') + ->each(function (Crawler $elm) use (&$anchors) { + + $imgTag = $elm->outerHtml(); + $alt = $elm->attr('alt'); + + $this->content = Str::of($this->content) + ->replace($imgTag, "$imgTag"); + }); + + $fixer = new Fixer([ + 'Ellipsis', + 'Dimension', + 'Unit', + 'Dash', + 'SmartQuotes', + 'NoSpaceBeforeComma', + 'CurlyQuote', + 'Trademark', + ]); + + $crawler + ->filter('p,liб,blockquote') + ->each(function (Crawler $elm) use ($fixer) { + + $content = $elm->html(); + + $paragraph = $fixer->fix($content); + + $this->content = Str::of($this->content)->replace($content, $paragraph); + }); + + return $this->content; + } + + /** + * @return string + * @throws \DOMException + */ + public function toHtml(): string + { + return $this->modifyContent(); + } +} diff --git a/composer.json b/composer.json index 3448ff05..92701200 100644 --- a/composer.json +++ b/composer.json @@ -5,10 +5,11 @@ "keywords": ["laravel", "framework"], "license": "MIT", "require": { - "php": ">=8.2", + "php": ">=8.1", "cagilo/cagilo": "^3.2", "doctrine/dbal": "^3.7", "guzzlehttp/guzzle": "^7.2", + "jolicode/jolitypo": "^1.4", "laravel/framework": "^10.10", "laravel/sanctum": "^3.2", "laravel/socialite": "^5.9", @@ -22,6 +23,7 @@ "fakerphp/faker": "^1.9.1", "laravel/pint": "^1.0", "laravel/sail": "^1.18", + "laravel/telescope": "^4.17", "mockery/mockery": "^1.4.4", "nunomaduro/collision": "^7.0", "phpunit/phpunit": "^10.1", @@ -56,7 +58,9 @@ }, "extra": { "laravel": { - "dont-discover": [] + "dont-discover": [ + "laravel/telescope" + ] } }, "config": { diff --git a/composer.lock b/composer.lock index e86cd51a..a8840559 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0a81bb4e1d13a5ecd09e05de78cacbb5", + "content-hash": "b9c02776a4b6ceaf66c5d15271dddd37", "packages": [ { "name": "brick/math", @@ -1517,6 +1517,68 @@ ], "time": "2020-06-13T08:05:20+00:00" }, + { + "name": "jolicode/jolitypo", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/jolicode/JoliTypo.git", + "reference": "d85b1076486b6886f1a16943d032d11b9c06c78d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jolicode/JoliTypo/zipball/d85b1076486b6886f1a16943d032d11b9c06c78d", + "reference": "d85b1076486b6886f1a16943d032d11b9c06c78d", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "lib-libxml": "*", + "org_heigl/hyphenator": "^2.6 || ^3.0", + "php": ">=7.4" + }, + "conflict": { + "ext-apc": "3.1.11" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.3.2", + "symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0", + "symfony/phpunit-bridge": "^5.4.8 || ^6.0", + "symfony/twig-bundle": "^4.4 || ^5.0 || ^6.0", + "symfony/yaml": "^4.4 || ^5.0 || ^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "JoliTypo\\": "src/JoliTypo" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Damien Alexandre", + "email": "dalexandre@jolicode.com", + "homepage": "https://damienalexandre.fr/" + } + ], + "description": "Microtypography fixer for the web.", + "homepage": "https://github.com/jolicode/JoliTypo", + "keywords": [ + "ellipsis", + "fixer", + "quote", + "smartquote", + "typography" + ], + "support": { + "issues": "https://github.com/jolicode/JoliTypo/issues", + "source": "https://github.com/jolicode/JoliTypo/tree/v1.4.0" + }, + "time": "2022-12-22T08:29:45+00:00" + }, { "name": "laravel/framework", "version": "v10.30.1", @@ -3194,6 +3256,58 @@ ], "time": "2023-02-18T22:44:06+00:00" }, + { + "name": "org_heigl/hyphenator", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/heiglandreas/Org_Heigl_Hyphenator.git", + "reference": "d8bcb8cefff21c9de3a77ec4de1750f0230a6494" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/heiglandreas/Org_Heigl_Hyphenator/zipball/d8bcb8cefff21c9de3a77ec4de1750f0230a6494", + "reference": "d8bcb8cefff21c9de3a77ec4de1750f0230a6494", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.2||^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "phpunit/phpunit": "^8.0||^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Org\\Heigl\\Hyphenator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Heigl", + "email": "andreas@heigl.org", + "homepage": "http://andreas.heigl.org", + "role": "Developer" + } + ], + "description": "Word-Hyphenation for PHP based on the TeX-Hyphenation algorithm", + "homepage": "http://github.com/heiglandreas/Org_Heigl_Hyphenator", + "keywords": [ + "hyphenate", + "hyphenation" + ], + "support": { + "issues": "https://github.com/heiglandreas/Org_Heigl_Hyphenator/issues", + "source": "https://github.com/heiglandreas/Org_Heigl_Hyphenator/tree/v3.0.0" + }, + "time": "2022-05-21T08:58:29+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.1", @@ -7122,6 +7236,77 @@ }, "time": "2023-10-18T13:57:15+00:00" }, + { + "name": "laravel/telescope", + "version": "v4.17.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/telescope.git", + "reference": "64da53ee46b99ef328458eaed32202b51e325a11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/telescope/zipball/64da53ee46b99ef328458eaed32202b51e325a11", + "reference": "64da53ee46b99ef328458eaed32202b51e325a11", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": "^8.37|^9.0|^10.0", + "php": "^8.0", + "symfony/var-dumper": "^5.0|^6.0" + }, + "require-dev": { + "ext-gd": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "laravel/octane": "^1.4", + "orchestra/testbench": "^6.0|^7.0|^8.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Telescope\\TelescopeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Telescope\\": "src/", + "Laravel\\Telescope\\Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Mohamed Said", + "email": "mohamed@laravel.com" + } + ], + "description": "An elegant debug assistant for the Laravel framework.", + "keywords": [ + "debugging", + "laravel", + "monitoring" + ], + "support": { + "issues": "https://github.com/laravel/telescope/issues", + "source": "https://github.com/laravel/telescope/tree/v4.17.2" + }, + "time": "2023-11-01T14:01:06+00:00" + }, { "name": "mockery/mockery", "version": "1.6.6", @@ -9174,7 +9359,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^8.1" + "php": ">=8.1" }, "platform-dev": [], "plugin-api-version": "2.3.0" diff --git a/resources/views/pages/docs.blade.php b/resources/views/pages/docs.blade.php index f4506197..11728993 100644 --- a/resources/views/pages/docs.blade.php +++ b/resources/views/pages/docs.blade.php @@ -6,7 +6,7 @@
-
+
@@ -14,6 +14,8 @@ --}} + +
    @foreach ($docs->getMenu() as $item)
  • @@ -25,10 +27,10 @@ class="btn btn-toggle d-flex align-items-center rounded border-0 collapsed text- {{ $item['title'] }} -
    -
    diff --git a/resources/views/particles/docs.blade.php b/resources/views/particles/docs.blade.php deleted file mode 100644 index 0e9c7dbf..00000000 --- a/resources/views/particles/docs.blade.php +++ /dev/null @@ -1 +0,0 @@ -{!! $content !!}