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; } }