🙈 Remove plugins from Git
All checks were successful
Deploy / deploy (push) Successful in 5s

This commit is contained in:
Marcel Kapfer 2024-03-17 23:04:19 +01:00
parent 11ffc370c2
commit 7a842eb58d
Signed by: mmk2410
GPG key ID: CADE6F0C09F21B09
11 changed files with 1 additions and 461 deletions

1
.gitignore vendored
View file

@ -68,3 +68,4 @@ Icon
# ---------------
/kirby
/site/plugins

View file

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2020-PRESENT Johann Schopplich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,135 +0,0 @@
# Kirby Highlighter
Server-side code highlighting available as [custom block](https://getkirby.com/docs/reference/panel/fields/blocks) and for [KirbyText](https://getkirby.com/docs/guide/content/text-formatting#kirbytext).
Built upon [highlight.php](http://www.highlightjs.org) which itself is a port of [highlight.js](http://www.highlightjs.org).
## Key Features
- 🏗 Works with Kirby's [`code` block](https://getkirby.com/docs/reference/panel/blocks/code)
- 🏳️‍🌈 Supports 189 languages
- 💫 94 styles available
- ⛳️ Automatic language detection for KirbyText
## Requirements
- Kirby 3.8+
## Installation
### Composer
```
composer require johannschopplich/kirby-highlighter
```
### Download
Download and copy this repository to `/site/plugins/kirby-highlighter`.
## Usage
### With Kirby Blocks Field
This plugin overwrites Kirby's internal [`code` block](https://getkirby.com/docs/reference/panel/blocks/code). Thus, you won't have to change a thing.
Use the `code` block just like before, the output will be highlighted automatically:
```yaml
fields:
example:
label: Paste code here
type: blocks
fieldsets:
- code
```
### Within KirbyText
Create a code block in your KirbyText field and optionally set the code language:
<pre lang="no-highlight"><code>```css
.currentColor {
color: currentColor;
}
```
</code></pre>
Or use the new `code`-KirbyTag from this plugin with a base64 encoded code string:
```
(code: LmN1cnJlbnRDb2xvciB7CiAgY29sb3I6IGN1cnJlbnRDb2xvcjsKfQ== lang: css)
```
Which outputs:
```html
<pre class="hljs"><code><span class="hljs-selector-class">.currentColor</span> {
<span class="hljs-attribute">color</span>: currentColor;
}</code></pre>
```
The syntax highlighting functionality can be changed. You can choose between two highlighting modes:
1. Explicit mode (default)
2. Automatic language detection mode (opt-in)
#### Explicit Mode
In explicit mode, you have to define which language the code block is. Otherwise highlighting will be skipped.
#### Automatic Language Detection
Alternatively you can use the automatic detection mode, which highlights your code with the language the library thinks is best. It is highly recommended you explicitly choose the language or limit the number of languages to automatically detect from. This reduces the number of inaccuracies and skips this extremely inefficient selection process.
To enable automatic language detection, set:
- `johannschopplich.highlighter.autodetect` to `true`
- `johannschopplich.highlighter.languages` to an array of names from which languages should be chosen
## Options
| Option |  Default | Description |
| --------------------------------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `johannschopplich.highlighter.class` | `hljs` | Style class for Highlight to be added to the `pre` element. |
| `johannschopplich.highlighter.autodetect` | `false` | Indicates if the library should define which language thinks is best. Only applies when no language was set on the KirbyText code block. |
| `johannschopplich.highlighter.languages` | `[]` | Array of language names to be auto-detected. If empty, every language will be auto-detectable. |
| `johannschopplich.highlighter.line-numbering` | `false` | Indicates if the library should split up the highlighted code on each new line and wrap it in a `<span>` element. |
| `johannschopplich.highlighter.line-numbering-class` | `hljs-code-line` | CSS class applied to highlighted code lines, respectively `<span>` elements. |
## Styling in the Frontend
Since this plugin handles highlighting code only and thus just wraps span's around code, you have to link styles in your frontend yourself. I recommend choosing one of the available themes directly from the highlight.js project: [highlight.js/src/styles/](https://github.com/highlightjs/highlight.js/tree/master/src/styles)
The CSS files over at the repository are maintained and new ones arrive from time to time, therefore it would be redundant to include a copy in this repository.
One of my favorite themes is [Night Owl by Sarah Drasner](https://github.com/highlightjs/highlight.js/blob/master/src/styles/night-owl.css).
For example you could download the CSS file and save it in your Kirby project under `assets/css/hljs-night-owl.css`. Now you just have to include it in your template `<?= css('assets/css/hljs-night-owl.css') ?>`. Alternatively, use a CSS bundler of your choice.
### Line Numbering
If you choose to activate the line numbering option, you will need to include additional CSS style to display line numbering.
A basic example using [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements):
```css
pre.hljs .hljs-code-line {
counter-increment: line;
}
pre.hljs .hljs-code-line::before {
content: counter(line);
display: inline-block;
margin-right: 1em;
opacity: 0.5;
}
```
## Credits
- Geert Bergman and contributors for the awesome [highlight.php](https://github.com/scrivo/highlight.php) port.
- Martin Folkers for his [Kirby Highlight](https://github.com/S1SYPHOS/kirby3-highlight) plugin which built the base of this package.
## License
[MIT](./LICENSE) License © 2020-PRESENT [Johann Schopplich](https://github.com/johannschopplich)

View file

@ -1,74 +0,0 @@
<?php
namespace JohannSchopplich;
use DOMDocument;
use DOMNode;
class HTML5DOMDocument extends DOMDocument
{
/**
* Name of temporary root element for the XML parser
*/
protected string $tempRoot = 'main';
/**
* Create a new HTML5-compatible document parser
*/
public function __construct(string $version = '1.0', string $encoding = 'UTF-8')
{
// Silence libxml errors with HTML5 elements
libxml_use_internal_errors(true);
// Call parent class
parent::__construct($version, $encoding);
}
/**
* Load HTML from string, make UTF-8 compatible and add temporary root element
*/
public function loadHTML(string $source, int $options = LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD): bool
{
// `loadHTML` will treat the string as being in ISO-8859-1 unless
// told otherwise, so translate anything above the ASCII range into
// its html entity equivalent
// @see https://stackoverflow.com/questions/39148170/utf-8-with-php-domdocument-loadhtml
$convertedSource = htmlspecialchars_decode(htmlentities($source, ENT_COMPAT, 'UTF-8'), ENT_QUOTES);
// Add fake root element for XML parser because it assumes that the
// first encountered tag is the root element
// @see https://stackoverflow.com/questions/39479994/php-domdocument-savehtml-breaks-format
return parent::loadHTML("<{$this->tempRoot}>" . $convertedSource . "</{$this->tempRoot}>", $options);
}
/**
* Strip the temporarily added root element
*/
private function unwrapTempRoot(string $output): string
{
if ($this->firstChild->nodeName === $this->tempRoot) {
return substr($output, strlen($this->tempRoot) + 2, -strlen($this->tempRoot) - 4);
}
return $output;
}
/**
* Dump the internal document into a HTML string
*/
#[\ReturnTypeWillChange]
public function saveHTML(DOMNode|null $node = null, bool $entities = false): string|false
{
$html = parent::saveHTML($node);
if ($entities === false) {
$html = html_entity_decode($html);
}
if ($node === null) {
$html = $this->unwrapTempRoot($html);
}
return $html;
}
}

View file

@ -1,49 +0,0 @@
{
"name": "johannschopplich/kirby-highlighter",
"description": "Server-side syntax highlighting for Kirby CMS",
"type": "kirby-plugin",
"version": "3.1.0",
"keywords": [
"kirby",
"highlight",
"highlighter",
"hljs"
],
"license": "MIT",
"homepage": "https://github.com/johannschopplich/kirby-highlighter#readme",
"authors": [
{
"name": "Johann Schopplich",
"email": "pkg@johannschopplich.com",
"homepage": "https://johannschopplich.com"
}
],
"require": {
"getkirby/composer-installer": "^1.2",
"scrivo/highlight.php": "^9.18"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "@stable",
"getkirby/cms": "^4",
"phpunit/phpunit": "^9.0"
},
"autoload": {
"psr-4": {
"JohannSchopplich\\": "classes/JohannSchopplich/"
}
},
"scripts": {
"fix": "php-cs-fixer fix",
"dist": "composer install --no-dev --optimize-autoloader",
"test": "phpunit"
},
"config": {
"optimize-autoloader": true,
"allow-plugins": {
"getkirby/composer-installer": true
}
},
"extra": {
"kirby-cms-path": "tests/fixtures/kirby"
}
}

View file

@ -1,23 +0,0 @@
<?php
if (!function_exists('is_base64_string_s')) {
// https://stackoverflow.com/a/51877882
function is_base64_string_s(string $str, $enc = ['UTF-8', 'ASCII'])
{
return !(($b = base64_decode($str, true)) === false) && in_array(mb_detect_encoding($b), $enc);
}
}
return [
'fromBase64' => function ($field) {
if ($field->isNotEmpty()) {
$value = trim((string)$field->value());
if (is_base64_string_s($value)) {
$field->value = base64_decode($value);
}
}
return $field;
},
];

View file

@ -1,86 +0,0 @@
<?php
use Highlight\Highlighter;
use JohannSchopplich\HTML5DOMDocument;
use Kirby\Cms\App;
return [
'kirbytext:after' => function (string|null $text) {
$kirby = App::instance();
// Parse KirbyText input as HTML document
$dom = new HTML5DOMDocument();
$dom->loadHTML($text);
// Retrieve all `pre` elements inside newly created HTML document
$preNodes = $dom->getElementsByTagName('pre');
// Bail if no `pre` elements have been found
if ($preNodes->length === 0) {
return $text;
}
// Loop through all `pre` elements
foreach ($preNodes as $preNode) {
// Ensure nothing but the `code` element exists
if ($preNode->childNodes->length !== 1) {
continue;
}
// Select direct `code` child element of `pre` block
$codeNode = $preNode->firstChild;
// Get language code if present
$language = $codeNode->getAttribute('class');
if (str_starts_with($language, 'language-')) {
$language = preg_replace('/^language-/', '', $language);
}
// Bail highlighting if language isn't set and auto detection is disabled
if (empty($language) && !$kirby->option('johannschopplich.highlighter.autodetect', false)) {
continue;
}
// Add `hljs` class to `pre` block
$preNode->setAttribute('class', $kirby->option('johannschopplich.highlighter.class', 'hljs'));
// Get raw code data to highlight
$code = $codeNode->nodeValue;
// Remove code element afterwards
$preNode->removeChild($codeNode);
// Initiate `Highlighter` and use pre-defined language code, fall
// back to language auto detection if enabled
$highlighter = new Highlighter();
// Highlight code
if (!empty($language)) {
$highlightedCode = $highlighter->highlight($language, $code);
} elseif ($kirby->option('johannschopplich.highlighter.autodetect', false)) {
$languageSubset = $kirby->option('johannschopplich.highlighter.languages', []);
if (!empty($languageSubset)) {
$highlighter->setAutodetectLanguages($languageSubset);
}
$highlightedCode = $highlighter->highlightAuto($code);
}
// Line numbering
if ($kirby->option('johannschopplich.highlighter.line-numbering', false)) {
$lines = preg_split('/\R/', $highlightedCode->value);
$lineClass = $kirby->option('johannschopplich.highlighter.line-numbering-class', 'hljs-code-line');
$highlightedCode->value = '<span class="' . $lineClass . '">' . implode("</span>\n<span class=\"$lineClass\">", $lines) . '</span>';
}
// Append highlighted wrapped in `code` block to parent `pre`
$codeNode = $dom->createDocumentFragment();
$codeNode->appendXML('<code data-language="' . $language . '">' . $highlightedCode->value . '</code>');
$preNode->appendChild($codeNode);
}
// Save all changes
$text = $dom->saveHTML(null, true);
return $text;
}
];

View file

@ -1,27 +0,0 @@
<?php
use Kirby\Cms\App;
return [
'code' => [
'attr' => [
'lang',
'language',
],
// TODO: Type as `\Kirby\Text\KirbyTag` for Kirby 4
'html' => function ($tag) {
$kirby = App::instance();
$code = $tag->value;
$language = $tag->lang ?? $tag->language;
$block = new \Kirby\Cms\Block([
'type' => 'code',
'content' => [
'language' => $language ?? 'plaintext',
'code' => is_base64_string_s($code) ? base64_decode($code) : $code,
]
]);
return $kirby->snippet('blocks/code', ['block' => $block], true);
}
]
];

View file

@ -1,12 +0,0 @@
<?php
@include_once __DIR__ . '/vendor/autoload.php';
\Kirby\Cms\App::plugin('johannschopplich/highlighter', [
'hooks' => require __DIR__ . '/extensions/hooks.php',
'fieldMethods' => require __DIR__ . '/extensions/fieldmethods.php',
'tags' => require __DIR__ . '/extensions/kirbytags.php',
'snippets' => [
'blocks/code' => __DIR__ . '/snippets/blocks/code.php'
]
]);

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="vendor/autoload.php"
colors="true"
verbose="true"
>
<testsuites>
<testsuite name="classes">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
</phpunit>

View file

@ -1,22 +0,0 @@
<?php
/** @var \Kirby\Cms\Block $block */
$highlighter = new \Highlight\Highlighter();
$language = $block->language()->value();
$code = $block->code()->fromBase64()->value();
if (empty($language) || !in_array($language, $highlighter->listRegisteredLanguages())) {
$language = 'plaintext';
}
$highlightedCode = $highlighter->highlight($language, $code)->value;
// Handle line numbering
if (option('johannschopplich.highlighter.line-numbering', false)) {
$lines = preg_split('/\R/', $highlightedCode);
$lineClass = option('johannschopplich.highlighter.line-numbering-class', 'hljs-code-line');
$highlightedCode = '<span class="' . $lineClass . '">' . implode("</span>\n<span class=\"$lineClass\">", $lines) . '</span>';
}
?>
<pre class="<?= option('johannschopplich.highlighter.class', 'hljs') ?>"><code data-language="<?= $language ?>"><?= $highlightedCode ?></code></pre>