From dc2305e2f96420219b741c70df86d6f452f15688 Mon Sep 17 00:00:00 2001 From: Seth Thompson Date: Sun, 29 Sep 2024 13:24:24 -0400 Subject: [PATCH] Re-add `getAvailableLanguages`, `getAvailableThemes`, `languageIsAvailable` and `themeIsAvailable` (#23) * add symfony/process dependency * Revert "Remove methods" This reverts commit cc1e02103e9a4166800653d31bfa977a229808ca. * read bundled languages and add support for aliases * read bundled themes * fix symfony/process version range --------- Co-authored-by: Rias --- bin/shiki.js | 25 +++++++++++++++++++++++++ composer.json | 2 +- src/Shiki.php | 32 ++++++++++++++++++++++++++++++++ tests/ShikiCustomRenderTest.php | 32 ++++++++++++++++++++++++++++++++ tests/ShikiTest.php | 32 ++++++++++++++++++++++++++++++++ tests/testfiles/alt-bin/shiki.js | 19 +++++++++++++++++-- 6 files changed, 139 insertions(+), 3 deletions(-) diff --git a/bin/shiki.js b/bin/shiki.js index 5e00269..798f543 100644 --- a/bin/shiki.js +++ b/bin/shiki.js @@ -37,6 +37,31 @@ async function main(args) { if (!customLanguages[language]) await highlighter.loadLanguage(language); + if (args[0] === 'languages') { + process.stdout.write( + JSON.stringify([ + ...Object.keys(shiki.bundledLanguagesBase), + ...Object.keys(customLanguages), + ]) + ); + return; + } + + if (args[0] === 'aliases') { + process.stdout.write( + JSON.stringify([ + ...Object.keys(shiki.bundledLanguages), + ...Object.keys(customLanguages), + ]) + ); + return; + } + + if (args[0] === 'themes') { + process.stdout.write(JSON.stringify(Object.keys(shiki.bundledThemes))); + return; + } + const { theme: theme$ } = highlighter.setTheme(theme) const result = highlighter.codeToTokens(args[0], { diff --git a/composer.json b/composer.json index 8316385..28fb205 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ "require": { "php": "^7.4|^8.0", "ext-json": "*", - "symfony/process": "^5.0|^6.0|^7.0" + "symfony/process": "^5.4|^6.4|^7.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "^v3.0", diff --git a/src/Shiki.php b/src/Shiki.php index 3d0f67c..955bbb7 100644 --- a/src/Shiki.php +++ b/src/Shiki.php @@ -37,11 +37,43 @@ public static function highlight( ]); } + public function getAvailableLanguages(): array + { + $shikiResult = $this->callShiki('languages'); + + $languages = json_decode($shikiResult, true); + + sort($languages); + + return $languages; + } + public function __construct(string $defaultTheme = 'nord') { $this->defaultTheme = $defaultTheme; } + public function getAvailableThemes(): array + { + $shikiResult = $this->callShiki('themes'); + + return json_decode($shikiResult, true); + } + + public function languageIsAvailable(string $language): bool + { + $shikiResult = $this->callShiki('aliases'); + + $aliases = json_decode($shikiResult, true); + + return in_array($language, $aliases); + } + + public function themeIsAvailable(string $theme): bool + { + return in_array($theme, $this->getAvailableThemes()); + } + public function highlightCode(string $code, string $language, ?string $theme = null, ?array $options = []): string { $theme = $theme ?? $this->defaultTheme; diff --git a/tests/ShikiCustomRenderTest.php b/tests/ShikiCustomRenderTest.php index fdf8882..0a950f3 100644 --- a/tests/ShikiCustomRenderTest.php +++ b/tests/ShikiCustomRenderTest.php @@ -129,3 +129,35 @@ Shiki::highlight($code, 'invalid-language'); })->throws(Exception::class); + +it('can get all available themes', function () { + $availableThemes = (new Shiki())->getAvailableThemes(); + + expect($availableThemes)->not()->toBeEmpty(); +}); + +it('can get all available languages', function () { + $availableLanguages = (new Shiki())->getAvailableLanguages(); + + expect($availableLanguages)->not()->toBeEmpty(); + expect($availableLanguages)->toContain('javascript'); + // should not include aliases + expect($availableLanguages)->not()->toContain('js'); +}); + +it('can determine that a theme is available', function () { + $shiki = (new Shiki()); + + expect($shiki->themeIsAvailable('nord'))->toBeTrue(); + expect($shiki->themeIsAvailable('non-existing-theme'))->toBeFalse(); +}); + +it('can determine that a language is available', function () { + $shiki = (new Shiki()); + + expect($shiki->languageIsAvailable('php'))->toBeTrue(); + expect($shiki->languageIsAvailable('non-existing-language'))->toBeFalse(); + expect($shiki->languageIsAvailable('javascript'))->toBeTrue(); + // should match aliases + expect($shiki->languageIsAvailable('js'))->toBeTrue(); +}); diff --git a/tests/ShikiTest.php b/tests/ShikiTest.php index 7cf74fb..6599740 100644 --- a/tests/ShikiTest.php +++ b/tests/ShikiTest.php @@ -126,3 +126,35 @@ Shiki::highlight($code, 'invalid-language'); })->throws(Exception::class); + +it('can get all available themes', function () { + $availableThemes = (new Shiki())->getAvailableThemes(); + + expect($availableThemes)->not()->toBeEmpty(); +}); + +it('can get all available languages', function () { + $availableLanguages = (new Shiki())->getAvailableLanguages(); + + expect($availableLanguages)->not()->toBeEmpty(); + expect($availableLanguages)->toContain('javascript'); + // should not include aliases + expect($availableLanguages)->not()->toContain('js'); +}); + +it('can determine that a theme is available', function () { + $shiki = (new Shiki()); + + expect($shiki->themeIsAvailable('nord'))->toBeTrue(); + expect($shiki->themeIsAvailable('non-existing-theme'))->toBeFalse(); +}); + +it('can determine that a language is available', function () { + $shiki = (new Shiki()); + + expect($shiki->languageIsAvailable('php'))->toBeTrue(); + expect($shiki->languageIsAvailable('non-existing-language'))->toBeFalse(); + expect($shiki->languageIsAvailable('javascript'))->toBeTrue(); + // should match aliases + expect($shiki->languageIsAvailable('js'))->toBeTrue(); +}); diff --git a/tests/testfiles/alt-bin/shiki.js b/tests/testfiles/alt-bin/shiki.js index c2ff3c1..2b3ffe2 100644 --- a/tests/testfiles/alt-bin/shiki.js +++ b/tests/testfiles/alt-bin/shiki.js @@ -38,12 +38,27 @@ async function main(args) { if (!customLanguages[language]) await highlighter.loadLanguage(language); if (args[0] === 'languages') { - process.stdout.write(JSON.stringify(highlighter.getLoadedLanguages())); + process.stdout.write( + JSON.stringify([ + ...Object.keys(shiki.bundledLanguagesBase), + ...Object.keys(customLanguages), + ]) + ); + return; + } + + if (args[0] === 'aliases') { + process.stdout.write( + JSON.stringify([ + ...Object.keys(shiki.bundledLanguages), + ...Object.keys(customLanguages), + ]) + ); return; } if (args[0] === 'themes') { - process.stdout.write(JSON.stringify(highlighter.getLoadedThemes())); + process.stdout.write(JSON.stringify(Object.keys(shiki.bundledThemes))); return; }