wiki-grav/plugins/prism-highlight/shortcodes/PrismShortcode.php
2023-06-02 11:39:36 +00:00

111 lines
4.2 KiB
PHP

<?php
namespace Grav\Plugin\Shortcodes;
use Grav\Common\Data\Data;
use Grav\Common\Uri;
use Grav\Common\Utils;
use Thunder\Shortcode\Shortcode\ProcessedShortcode;
class PrismShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getRawHandlers()->add('prism', function(ProcessedShortcode $sc) {
$config = new Data($this->config->get('plugins.prism-highlight'));
$content = $sc->getContent();
$git = $sc->getParameter('git');
if ($git) {
$content = $this->processGit($git) ?? $content;
}
$classes = $sc->getParameter('classes', $this->getBbCode($sc)) ?: 'language-text';
$id = $sc->getParameter('id');
$highlight_lines = $sc->getParameter('highlight');
$enable_line_numbers = (bool) Utils::contains($classes, 'line-numbers') ?: $config->get('plugins.line-numbers');
$enable_command_line = (bool) Utils::contains($classes, 'command-line') ?: $config->get('plugins.command-line');
$ln_start = $sc->getParameter('ln-start');
$cl_prompt = $sc->getParameter('cl-prompt', $config->get('plugins.command-line-prompt'));
$cl_output = $sc->getParameter('cl-output');
$cl_filter_output = $sc->getParameter('cl-filter-output');
$cl_continuation = $sc->getParameter('cl-continuation');
// work around \\ not being passed along as \
if ($cl_continuation == '\\\\')
$cl_continuation = '\\';
return $this->twig->processTemplate('shortcodes/prism-highlight.html.twig', [
'content' => trim($content),
'classes' => $classes,
'id' => $id,
'enable_line_numbers' => $enable_line_numbers,
'enable_command_line' => $enable_command_line,
'cl_prompt' => $cl_prompt,
'cl_output' => $cl_output,
'cl_filter_output' => $cl_filter_output,
'ln_start' => $ln_start,
'highlight_lines' => $highlight_lines,
'cl_continuation' => $cl_continuation,
]);
});
}
protected function processGit($path)
{
$content = null;
try {
$path = preg_replace(['#http[s]*:\/\/github.com\/#', '#\/blob\/#'], ['https://raw.github.com/', '/'], $path);
preg_match('#\?slice=(.*)#', $path, $matches);
// Ensure only 'extenral' URls are allowed..
if (!Uri::isExternal($path)) {
throw new \Exception('Local files are not allowed');
}
if ($path) {
$git_file = file_get_contents($path);
$lines = $matches[1] ?? null;
if ($lines && $git_file) {
$file_lines = explode("\n", $git_file);
//rejig things so it's the array is index starting at line #1
array_unshift($file_lines,"");
unset($file_lines[0]);
$specific_lines = explode(':', $lines);
if (count($specific_lines) === 1) {
$content = $file_lines[$specific_lines[0]] ?? $git_file;
} elseif (count($specific_lines) === 2) {
$start = $specific_lines[0];
$end = $specific_lines[1];
if ($end < 0) {
$end = count($file_lines) + $end;
}
$new_content = '';
foreach ($file_lines as $line_no => $line) {
if ($line_no >= $start && $line_no <= $end) {
$new_content .= $line . "\n";
}
}
$content = $new_content;
}
} else {
$content = $git_file;
}
} else {
throw new \Exception('File not found');
}
} catch (\exception $e) {
$msg = $e->getMessage() ?? 'Could not find';
$content = "$msg: " . $path;
}
return $content;
}
}