├── .gitignore ├── README.md ├── banner.png ├── composer.json ├── composer.lock ├── dist ├── styles-dark.css └── styles-light.css ├── mix-manifest.json ├── package-lock.json ├── package.json ├── phpunit.xml.dist ├── src ├── Facades │ └── GitDown.php ├── GitDown.php ├── GitDownServiceProvider.php ├── config-stub.php └── sass │ ├── styles-dark.scss │ └── styles-light.scss ├── tests └── GitDownTest.php ├── webpack.mix.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | node_modules/ 3 | .idea/ 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![GitDown - a simple package to parse markdown in PHP](banner.png) 2 | 3 | # GitDown 4 | A simple package for parsing (GitHub Flavored) Markdown in PHP. 5 | 6 | ## WARNING 7 | This package is a fraud. All it does is fire off your markdown to a [public GitHub API](https://developer.github.com/v3/markdown/) that returns the parsed result. 8 | 9 | Knowing this, if you don't store the result, or take advantage of the provided caching features, you'll end up with slow page loads, or worse, rate-limit errors from GitHub. 10 | 11 | Markdown parsing is super annoying, and this tradeoff is well worth it to me, I hope you embrace it as well. 12 | 13 | ## Installation 14 | 15 | ```bash 16 | composer require calebporzio/gitdown 17 | ``` 18 | 19 | ## TLDR; 20 | 21 | ```php 22 | // Optionally set a GitHub Personal Access Token to increase rate-limit. 23 | GitDown::setToken($token); 24 | 25 | GitDown::parse($markdown); 26 | 27 | // Uses Laravel's cache()->rememberForever() under the hood. 28 | GitDown::parseAndCache($markdown); 29 | ``` 30 | 31 | Optionally, add the `@gitdown` snippet to your template's `` section, and a `.markdown-body` class to a wrapper element, for GitHub markdown/code-syntax styling. 32 | 33 | ```html 34 | 35 | [...] 36 | @gitdown 37 | 38 | 39 |
40 | {!! GitDown::parseAndCache($content) !!} 41 |
42 | 43 | ``` 44 | 45 | ## Authenticating With GitHub 46 | 47 | Without authentication, GitHub will limit your API calls to 60 calls/hour. If you use authentication tokens, you can increase this limit to 5000 calls/minute. It is highly recommended that you use a "Personal Access Token" with this package. To obtain one, [click here](https://github.com/settings/tokens). (You can leave the permissions blank for this token.) 48 | 49 | First, publish the package's config file. 50 | 51 | `php artisan vendor:publish --provider="GitDown\GitDownServiceProvider"` 52 | 53 | Then, add the following entry to your `.env` file. 54 | 55 | ``` 56 | [...] 57 | GITHUB_TOKEN=your-token-here 58 | ``` 59 | 60 | ## Usage 61 | ```php 62 | GitDown::parse($markdown); 63 | 64 | // Will be cached forever. (suggested) 65 | GitDown::parseAndCache($markdown); 66 | 67 | // Will be cached for 24 hours. (minutes in Laravel < 5.8, seconds otherwise) 68 | GitDown::parseAndCache($markdown, $seconds = 86400); 69 | 70 | // Pass in your own custom caching strategy. 71 | GitDown::parseAndCache($markdown, function ($parse) { 72 | return Cache::rememberForever(sha1($markdown), function () use ($parse) { 73 | return $parse(); 74 | }); 75 | }); 76 | ``` 77 | 78 | ## Allowing Dangerous Tags 79 | By default, GitHub sanitizes HTML tags it deems "unsafe" like `" will output 38 | | "<iframe></iframe>". Specify tags you want to preserve. 39 | | 40 | */ 41 | 42 | 'allowedTags' => [], 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Syntax Highlight Theme 47 | |-------------------------------------------------------------------------- 48 | | 49 | | Available options are `light` and `dark`. 50 | | 51 | */ 52 | 53 | 'syntaxTheme' => 'light', 54 | 55 | ]; 56 | -------------------------------------------------------------------------------- /src/sass/styles-dark.scss: -------------------------------------------------------------------------------- 1 | 2 | // The "markdown" component of Github's Primer CSS library. 3 | @import "primer-markdown/index.scss"; 4 | 5 | // Github's "light" theme for syntax highlighting. 6 | @import "./../../node_modules/github-syntax-dark/lib/github-dark.css"; 7 | -------------------------------------------------------------------------------- /src/sass/styles-light.scss: -------------------------------------------------------------------------------- 1 | 2 | // The "markdown" component of Github's Primer CSS library. 3 | @import "primer-markdown/index.scss"; 4 | 5 | // Github's "light" theme for syntax highlighting. 6 | @import "./../../node_modules/github-syntax-light/lib/github-light.css"; 7 | -------------------------------------------------------------------------------- /tests/GitDownTest.php: -------------------------------------------------------------------------------- 1 | parse(<<assertEquals(<<foo

22 |

bar

23 | EOT 24 | , trim($parsed)); 25 | } 26 | 27 | /** @test */ 28 | public function can_provide_caching_strategy() 29 | { 30 | $numberOfTimesGitHubWasCalled = 0; 31 | 32 | $firstResult = (new GitDown)->parseAndCache('**foo**', $this->cacheStrategy($numberOfTimesGitHubWasCalled)); 33 | $secondResult = (new GitDown)->parseAndCache('**foo**', $this->cacheStrategy($numberOfTimesGitHubWasCalled)); 34 | 35 | $this->assertEquals('

foo

', trim($firstResult)); 36 | $this->assertEquals('cached', $secondResult); 37 | } 38 | 39 | protected function cacheStrategy(&$callCount) 40 | { 41 | return function ($parse) use (&$callCount) { 42 | if ($callCount < 1) { 43 | $callCount++; 44 | return $parse(); 45 | } else { 46 | return 'cached'; 47 | } 48 | }; 49 | } 50 | 51 | /** @test */ 52 | public function parsed_html_preserves_dangerous_tags() 53 | { 54 | $parsed = (new GitDown(null, null, $allowedTags = ['iframe', 'script']))->parse(''); 55 | 56 | $this->assertEquals('

', trim($parsed)); 57 | } 58 | 59 | /** @test */ 60 | public function can_get_the_styles() 61 | { 62 | $gitDown = new GitDown(null, null, $allowedTags = ['iframe', 'script']); 63 | 64 | $this->assertSame(file_get_contents(__DIR__ . '/../dist/styles-light.css'), $gitDown->styles()); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | const mix = require('laravel-mix'); 2 | 3 | mix.sass('src/sass/styles-light.scss', 'dist/styles-light.css'); 4 | 5 | mix.sass('src/sass/styles-dark.scss', 'dist/styles-dark.css'); --------------------------------------------------------------------------------