Skip to content

Commit

Permalink
feat: upgrade support to shiki v1 (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
heywhy authored Feb 19, 2024
1 parent aa05eda commit 3675da7
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 226 deletions.
113 changes: 56 additions & 57 deletions bin/shiki.js
Original file line number Diff line number Diff line change
@@ -1,84 +1,83 @@
const shiki = require('shiki');
const fs = require('fs');
const path = require('path');
const renderer = require('./renderer');
const args = JSON.parse(process.argv.slice(2));

const arguments = JSON.parse(process.argv.slice(2));

const customLanguages = [
{
id: 'antlers',
const customLanguages = {
antlers: {
scopeName: 'text.html.statamic',
path: getLanguagePath('antlers'),
embeddedLangs: ['html'],
},
{
id: 'blade',
blade: {
scopeName: 'text.html.php.blade',
path: getLanguagePath('blade'),
embeddedLangs: ['html', 'php'],
},
];
};

if (arguments[0] === 'themes') {
process.stdout.write(JSON.stringify(shiki.BUNDLED_THEMES));
return;
}
async function main(args) {
const shiki = await import('shiki');
const highlighter = await shiki.getHighlighter({});

let allLanguages = shiki.BUNDLED_LANGUAGES;
allLanguages.push(...customLanguages);
for (const [lang, spec] of Object.entries(customLanguages)) {
for (const embedded of spec.embeddedLangs) {
await highlighter.loadLanguage(embedded);
}

if (arguments[0] === 'languages') {
process.stdout.write(JSON.stringify(allLanguages));
return;
}
await highlighter.loadLanguage({ ...spec, ...loadLanguage(lang), name: lang });
}

const language = args[1] || 'php';
let theme = args[2] || 'nord';

const language = arguments[1] || 'php';
let theme = arguments[2] || 'nord';
if (fs.existsSync(theme)) {
theme = JSON.parse(fs.readFileSync(theme, 'utf-8'));
} else {
await highlighter.loadTheme(theme);
}

const languagesToLoad = allLanguages.filter(lang => lang.id === language || (lang.aliases && lang.aliases.includes(language)));
if (!customLanguages[language]) await highlighter.loadLanguage(language);

(function loadEmbeddedLangsRecursively() {
languagesToLoad.forEach(function (language) {
const embeddedLangs = language.embeddedLangs || [];
embeddedLangs.forEach(function (languageKey) {
if (languagesToLoad.find(lang => lang.id === languageKey || (lang.aliases && lang.aliases.includes(languageKey)))) {
return;
}
if (args[0] === 'languages') {
process.stdout.write(JSON.stringify(highlighter.getLoadedLanguages()));
return;
}

languagesToLoad.push(allLanguages.find(lang => lang.id === languageKey || (lang.aliases && lang.aliases.includes(languageKey))));
loadEmbeddedLangsRecursively();
});
if (args[0] === 'themes') {
process.stdout.write(JSON.stringify(highlighter.getLoadedThemes()));
return;
}

const { theme: theme$ } = highlighter.setTheme(theme)

const result = highlighter.codeToTokens(args[0], {
theme: theme$,
lang: language,
});
})();

if (fs.existsSync(theme)) {
theme = JSON.parse(fs.readFileSync(theme, 'utf-8'));
}
const options = args[3] || {};

shiki.getHighlighter({
theme,
langs: languagesToLoad,
}).then((highlighter) => {
const tokens = highlighter.codeToThemedTokens(arguments[0], language);
const theme = highlighter.getTheme();
const options = arguments[3] || {};

process.stdout.write(renderer.renderToHtml(tokens, {
fg: theme.fg,
bg: theme.bg,
const rendered = renderer.renderToHtml(result.tokens, {
fg: theme$.fg,
bg: theme$.bg,
highlightLines: options.highlightLines,
addLines: options.addLines,
deleteLines: options.deleteLines,
focusLines: options.focusLines,
}));
});
});

process.stdout.write(rendered);
}

function getLanguagePath(language)
{
const pathToShikiDistDirectory = path.dirname(require.resolve('shiki'));
const pathToShikiLanguages = path.resolve(`${pathToShikiDistDirectory}/../languages`);
const relativeDirectory = path.relative(pathToShikiLanguages, `${__dirname}/../languages`);
main(args)

function loadLanguage(language) {
const path = getLanguagePath(language);
const content = fs.readFileSync(path);

return JSON.parse(content);
}
function getLanguagePath(language) {
const url = path.join(__dirname, '..', 'languages', `${language}.tmLanguage.json`);

return `${relativeDirectory}/${language}.tmLanguage.json`
return path.normalize(url);
}
114 changes: 10 additions & 104 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
"author": "Spatie",
"license": "MIT",
"dependencies": {
"shiki": "^0.9.5"
"shiki": "^1.1.3"
}
}
9 changes: 2 additions & 7 deletions src/Shiki.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,7 @@ public function getAvailableLanguages(): array
{
$shikiResult = $this->callShiki('languages');

$languageProperties = json_decode($shikiResult, true);

$languages = array_map(
fn ($properties) => $properties['id'],
$languageProperties
);
$languages = json_decode($shikiResult, true);

sort($languages);

Expand Down Expand Up @@ -112,7 +107,7 @@ protected function callShiki(...$arguments): string

$process->run();

if (! $process->isSuccessful()) {
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}

Expand Down
Loading

0 comments on commit 3675da7

Please sign in to comment.