diff --git a/app/Livewire/RepositoryDetails.php b/app/Livewire/RepositoryDetails.php index 0778128..60eff63 100644 --- a/app/Livewire/RepositoryDetails.php +++ b/app/Livewire/RepositoryDetails.php @@ -5,6 +5,7 @@ use App\Models\Repository; use CzProject\GitPhp\Git; use CzProject\GitPhp\GitRepository; +use Illuminate\Support\Facades\Process; use Livewire\Component; class RepositoryDetails extends Component @@ -24,6 +25,8 @@ public function render() $tree = $repo->execute('ls-tree', "--format='%(objectmode) %(objecttype) %(objectname) %(path)", 'HEAD'); $objects = []; + $readmeMarkdown = implode(PHP_EOL, $repo->execute('show', 'HEAD:readme.md')); + foreach ($tree as $object) { $data = explode(' ', $object); @@ -50,6 +53,14 @@ public function render() $folders = array_filter($objects, fn ($object) => $object['type'] === 'tree'); $files = array_filter($objects, fn ($object) => $object['type'] === 'blob'); - return view('livewire.repository-details', compact(['branches', 'tags', 'objects', 'commits', 'folders', 'files']))->extends('layouts.app'); + return view('livewire.repository-details', compact([ + 'branches', + 'tags', + 'objects', + 'commits', + 'folders', + 'files', + 'readmeMarkdown', + ]))->extends('layouts.app'); } } diff --git a/composer.json b/composer.json index caa8824..09c111b 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ "laravel/sanctum": "^3.3", "laravel/tinker": "^2.8", "livewire/livewire": "^3.3", - "monolog/monolog": "^3.5" + "monolog/monolog": "^3.5", + "sinnbeck/markdom": "^2.0" }, "require-dev": { "fakerphp/faker": "^1.9.1", diff --git a/composer.lock b/composer.lock index eac7cfd..331a198 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": "c8cf7937d513222761721bb8c2921df3", + "content-hash": "411ed78f9f43e81c4d685857b6482dd4", "packages": [ { "name": "blade-ui-kit/blade-icons", @@ -776,6 +776,55 @@ ], "time": "2023-10-12T05:21:21+00:00" }, + { + "name": "gajus/dindent", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/gajus/dindent.git", + "reference": "d81c3a6f78fbe1ab26f5e753098bbbef6b6a9f3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/gajus/dindent/zipball/d81c3a6f78fbe1ab26f5e753098bbbef6b6a9f3c", + "reference": "d81c3a6f78fbe1ab26f5e753098bbbef6b6a9f3c", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "autoload": { + "psr-4": { + "Gajus\\Dindent\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Gajus Kuizinas", + "email": "gk@anuary.com" + } + ], + "description": "HTML indentation library for development and testing.", + "homepage": "https://github.com/gajus/dindent", + "keywords": [ + "format", + "html", + "indent" + ], + "support": { + "issues": "https://github.com/gajus/dindent/issues", + "source": "https://github.com/gajus/dindent/tree/master" + }, + "time": "2014-10-08T10:03:04+00:00" + }, { "name": "graham-campbell/result-type", "version": "v1.1.2", @@ -2428,6 +2477,73 @@ ], "time": "2024-01-02T14:29:17+00:00" }, + { + "name": "masterminds/html5", + "version": "2.8.1", + "source": { + "type": "git", + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Masterminds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Butcher", + "email": "technosophos@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + } + ], + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", + "keywords": [ + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" + ], + "support": { + "issues": "https://github.com/Masterminds/html5-php/issues", + "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" + }, + "time": "2023-05-10T11:58:31+00:00" + }, { "name": "monolog/monolog", "version": "3.5.0", @@ -3719,6 +3835,142 @@ ], "time": "2023-11-08T05:53:05+00:00" }, + { + "name": "scrivo/highlight.php", + "version": "v9.18.1.10", + "source": { + "type": "git", + "url": "https://github.com/scrivo/highlight.php.git", + "reference": "850f4b44697a2552e892ffe71490ba2733c2fc6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/850f4b44697a2552e892ffe71490ba2733c2fc6e", + "reference": "850f4b44697a2552e892ffe71490ba2733c2fc6e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=5.4" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.7", + "sabberworm/php-css-parser": "^8.3", + "symfony/finder": "^2.8|^3.4|^5.4", + "symfony/var-dumper": "^2.8|^3.4|^5.4" + }, + "suggest": { + "ext-mbstring": "Allows highlighting code with unicode characters and supports language with unicode keywords" + }, + "type": "library", + "autoload": { + "files": [ + "HighlightUtilities/functions.php" + ], + "psr-0": { + "Highlight\\": "", + "HighlightUtilities\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Geert Bergman", + "homepage": "http://www.scrivo.org/", + "role": "Project Author" + }, + { + "name": "Vladimir Jimenez", + "homepage": "https://allejo.io", + "role": "Maintainer" + }, + { + "name": "Martin Folkers", + "homepage": "https://twobrain.io", + "role": "Contributor" + } + ], + "description": "Server side syntax highlighter that supports 185 languages. It's a PHP port of highlight.js", + "keywords": [ + "code", + "highlight", + "highlight.js", + "highlight.php", + "syntax" + ], + "support": { + "issues": "https://github.com/scrivo/highlight.php/issues", + "source": "https://github.com/scrivo/highlight.php" + }, + "funding": [ + { + "url": "https://github.com/allejo", + "type": "github" + } + ], + "time": "2022-12-17T21:53:22+00:00" + }, + { + "name": "sinnbeck/markdom", + "version": "v2.0", + "source": { + "type": "git", + "url": "https://github.com/sinnbeck/markdom.git", + "reference": "de9c441bb0488614b7b03a6fc364dce13e4666cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sinnbeck/markdom/zipball/de9c441bb0488614b7b03a6fc364dce13e4666cf", + "reference": "de9c441bb0488614b7b03a6fc364dce13e4666cf", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "gajus/dindent": "^2.0", + "league/commonmark": "^2.0", + "scrivo/highlight.php": "^9.18.1.3", + "wa72/htmlpagedom": "^3.0" + }, + "require-dev": { + "orchestra/testbench": "^6.0|^7.0", + "pestphp/pest": "^1.0", + "phpunit/phpunit": "9.3.10", + "spatie/pest-plugin-snapshots": "^1.0", + "symfony/var-dumper": "^5.1" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Sinnbeck\\Markdom\\MarkdomServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Sinnbeck\\Markdom\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "René Sinnbeck", + "email": "rene.sinnbeck@gmail.com" + } + ], + "description": "Converts markdown to html with classes", + "support": { + "issues": "https://github.com/sinnbeck/markdom/issues", + "source": "https://github.com/sinnbeck/markdom/tree/v2.0" + }, + "time": "2022-07-25T13:21:50+00:00" + }, { "name": "symfony/console", "version": "v6.4.2", @@ -3945,6 +4197,73 @@ ], "time": "2023-05-23T14:45:45+00:00" }, + { + "name": "symfony/dom-crawler", + "version": "v7.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "d13205f444a535f4a6e52186aedbc99664f66a86" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/d13205f444a535f4a6e52186aedbc99664f66a86", + "reference": "d13205f444a535f4a6e52186aedbc99664f66a86", + "shasum": "" + }, + "require": { + "masterminds/html5": "^2.6", + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "symfony/css-selector": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases DOM navigation for HTML and XML documents", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dom-crawler/tree/v7.0.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-11-20T16:43:42+00:00" + }, { "name": "symfony/error-handler", "version": "v6.4.0", @@ -6187,6 +6506,73 @@ ], "time": "2022-03-08T17:03:00+00:00" }, + { + "name": "wa72/htmlpagedom", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/wasinger/htmlpagedom.git", + "reference": "9fa7dfea493e913e81a2b0f8d61f7a94324a04ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wasinger/htmlpagedom/zipball/9fa7dfea493e913e81a2b0f8d61f7a94324a04ea", + "reference": "9fa7dfea493e913e81a2b0f8d61f7a94324a04ea", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^8.0", + "symfony/css-selector": "^6.0 || ^7.0", + "symfony/dom-crawler": "^6.0 || ^7.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "clean/phpdoc-md": "^0.19.3", + "mikey179/vfsstream": "^1.6.10", + "phpunit/phpunit": "^9", + "scrutinizer/ocular": "^1.9", + "wa72/html-pretty-min": "~0.1" + }, + "suggest": { + "wa72/html-pretty-min": "Minify or indent HTML documents" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Wa72\\HtmlPageDom\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christoph Singer", + "email": "singer@webagentur72.de", + "homepage": "http://www.webagentur72.de" + } + ], + "description": "jQuery-inspired DOM manipulation extension for Symfony's Crawler", + "homepage": "http://github.com/wasinger/htmlpagedom", + "keywords": [ + "crawler", + "dom", + "html" + ], + "support": { + "issues": "https://github.com/wasinger/htmlpagedom/issues", + "source": "https://github.com/wasinger/htmlpagedom/tree/v3.0.2" + }, + "time": "2023-12-05T20:36:58+00:00" + }, { "name": "webmozart/assert", "version": "1.11.0", diff --git a/config/app.php b/config/app.php index 9207160..41e8623 100644 --- a/config/app.php +++ b/config/app.php @@ -183,6 +183,7 @@ 'aliases' => Facade::defaultAliases()->merge([ // 'Example' => App\Facades\Example::class, + 'Markdom' => Sinnbeck\Markdom\Facades\Markdom::class, ])->toArray(), ]; diff --git a/config/markdom.php b/config/markdom.php new file mode 100644 index 0000000..b44d2d2 --- /dev/null +++ b/config/markdom.php @@ -0,0 +1,162 @@ + 'lead', + * will give all
elements the class "lead" + *
+ */ + 'classes' => [ + // + ], + + /** + * Options for CommonMark parser + * https://commonmark.thephpleague.com/2.3/configuration/ + */ + 'commonmark' => [ + 'renderer' => [ + 'block_separator' => "\n", + 'inner_separator' => "\n", + 'soft_break' => "\n", + ], + + 'commonmark' => [ + 'enable_em' => true, + 'enable_strong' => true, + 'use_asterisk' => true, + 'use_underscore' => true, + 'unordered_list_markers' => ['-', '+', '*'], + ], + + /* + |-------------------------------------------------------------------------- + | HTML Input + |-------------------------------------------------------------------------- + | + | This option specifies how to handle untrusted HTML input. + | + | Default: 'strip' + | + */ + + 'html_input' => 'strip', + + /* + |-------------------------------------------------------------------------- + | Allow Unsafe Links + |-------------------------------------------------------------------------- + | + | This option specifies whether to allow risky image URLs and links. + | + | Default: true + | + */ + + 'allow_unsafe_links' => true, + + /* + |-------------------------------------------------------------------------- + | Maximum Nesting Level + |-------------------------------------------------------------------------- + | + | This option specifies the maximum permitted block nesting level. + | + | Default: PHP_INT_MAX + | + */ + + 'max_nesting_level' => PHP_INT_MAX, + + /* + |-------------------------------------------------------------------------- + | Slug Normalizer + |-------------------------------------------------------------------------- + | + | This option specifies an array of options for slug normalization. + | + | Default: [ + | 'max_length' => 255, + | 'unique' => 'document', + | ] + | + */ + + 'slug_normalizer' => [ + 'max_length' => 255, + 'unique' => 'document', + ], + ], + + /** + * Extensions for commonmark + * https://commonmark.thephpleague.com/2.3/extensions/overview/ + */ + 'commonmark_extensions' => [ + League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension::class, + // League\CommonMark\Extension\Autolink\AutolinkExtension::class, + // League\CommonMark\Extension\Strikethrough\StrikethroughExtension::class, + ], + + /** + * It is possible to have code tags automatically + * parsed and highlighted + * + * Remember to add the stylesheet to your page, if using this! + * @markdomStyles() + */ + 'code_highlight' => [ + 'enabled' => true, + 'theme' => 'default', + 'languages' => [ + 'javascript', + 'php', + 'css', + ], + ], + + /** + * This being enabled adds an id and an (invisible) anchor tag to configured elements + */ + 'links' => [ + 'enabled' => true, + + /** + * Here you can define which elements will receive id tags + */ + 'elements' => [ + 'h2', + 'h3', + 'h4', + ], + + /** + * Set the delimiter to use when creating id and href slugs + */ + 'slug_delimiter' => '-', + + /** + * Whether to add an achor tag + */ + 'add_anchor' => true, + + /** + * Here you can define where the anchor shall be placed, possible values: + * - before: the anchor tag will be placed right before the element + * - Example: