Add server side highlighting, fixes #139
Dieser Commit ist enthalten in:
Ursprung
57b3848430
Commit
92db87e00d
@ -27,7 +27,8 @@
|
||||
"symfony/polyfill-intl-icu": "^1.10",
|
||||
"symfony/process": "^4.0",
|
||||
"webuni/commonmark-table-extension": "0.9.*",
|
||||
"webuni/front-matter": "^1.0.0"
|
||||
"webuni/front-matter": "^1.0.0",
|
||||
"scrivo/highlight.php": "^9.15"
|
||||
},
|
||||
"suggest":{
|
||||
"ext-intl": "Allows to translate the modified at date"
|
||||
|
81
composer.lock
generiert
81
composer.lock
generiert
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "c2a8f08a3622dfcd70136f48e4f5a0ce",
|
||||
"content-hash": "3df8e368fea890f0e123788f898cddc9",
|
||||
"packages": [
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
@ -244,9 +244,9 @@
|
||||
"authors": [
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"role": "Lead Developer",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "https://www.colinodell.com"
|
||||
"homepage": "https://www.colinodell.com",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"description": "PHP Markdown parser based on the CommonMark spec",
|
||||
@ -500,6 +500,73 @@
|
||||
"description": "A polyfill for getallheaders.",
|
||||
"time": "2016-02-11T07:05:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "scrivo/highlight.php",
|
||||
"version": "v9.15.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/scrivo/highlight.php.git",
|
||||
"reference": "9ad3adb4456dc91196327498dbbce6aa1ba1239e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/scrivo/highlight.php/zipball/9ad3adb4456dc91196327498dbbce6aa1ba1239e",
|
||||
"reference": "9ad3adb4456dc91196327498dbbce6aa1ba1239e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8|^5.7",
|
||||
"symfony/finder": "^2.8"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "Needed to make use of the features in the utilities namespace"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Highlight\\": "",
|
||||
"HighlightUtilities\\": ""
|
||||
},
|
||||
"files": [
|
||||
"HighlightUtilities/functions.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Geert Bergman",
|
||||
"role": "Project Author",
|
||||
"homepage": "http://www.scrivo.org/"
|
||||
},
|
||||
{
|
||||
"name": "Vladimir Jimenez",
|
||||
"role": "Contributor",
|
||||
"homepage": "https://allejo.io"
|
||||
},
|
||||
{
|
||||
"name": "Martin Folkers",
|
||||
"role": "Contributor",
|
||||
"homepage": "https://twobrain.io"
|
||||
}
|
||||
],
|
||||
"description": "Server side syntax highlighter that supports 185 languages. It's a PHP port of highlight.js",
|
||||
"keywords": [
|
||||
"code",
|
||||
"highlight",
|
||||
"highlight.js",
|
||||
"highlight.php",
|
||||
"syntax"
|
||||
],
|
||||
"time": "2019-08-27T04:27:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v4.3.4",
|
||||
@ -1503,8 +1570,8 @@
|
||||
"authors": [
|
||||
{
|
||||
"name": "Frank Kleine",
|
||||
"homepage": "http://frankkleine.de/",
|
||||
"role": "Developer"
|
||||
"role": "Developer",
|
||||
"homepage": "http://frankkleine.de/"
|
||||
}
|
||||
],
|
||||
"description": "Virtual file system to mock the real file system in unit tests.",
|
||||
@ -2018,8 +2085,8 @@
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de",
|
||||
"role": "lead"
|
||||
"role": "lead",
|
||||
"email": "sebastian@phpunit.de"
|
||||
}
|
||||
],
|
||||
"description": "Utility class for timing",
|
||||
|
@ -2,21 +2,27 @@ Highlight.js highlights syntax in code examples on blogs, forums and in fact on
|
||||
|
||||
You can even use [Github Flavored Markdown](!Features/CommonMark_compliant)
|
||||
|
||||
We also use the [scrivo/highlight.php](https://github.com/scrivo/highlight.php) package to highlight on rendering when possible.
|
||||
Highlight.js is a powerful but heavy library, since we don't know which languages you'll use we included all of them.
|
||||
|
||||
The good news is; if you use a fenced code block (` ``` `) with the language defined, the rendering is done on server side and entirely skips loading Highlight.js on the page. While still having the same end-result on your code.
|
||||
|
||||
|
||||
**Python**
|
||||
|
||||
@requires_authorization
|
||||
def somefunc(param1='', param2=0):
|
||||
r'''A docstring'''
|
||||
if param1 > param2: # interesting
|
||||
print 'Gre\'ater'
|
||||
return (param2 - param1 + 1) or None
|
||||
```python
|
||||
@requires_authorization
|
||||
def somefunc(param1='', param2=0):
|
||||
r'''A docstring'''
|
||||
if param1 > param2: # interesting
|
||||
print 'Gre\'ater'
|
||||
return (param2 - param1 + 1) or None
|
||||
|
||||
class SomeClass:<br> pass
|
||||
|
||||
>>> message = '''interpreter
|
||||
... prompt'''
|
||||
class SomeClass:<br> pass
|
||||
|
||||
>>> message = '''interpreter
|
||||
... prompt'''
|
||||
```
|
||||
|
||||
**Python's profiler output**
|
||||
|
||||
|
@ -9,6 +9,8 @@ class CommonMarkConverter extends \Todaymade\Daux\ContentTypes\Markdown\CommonMa
|
||||
{
|
||||
parent::extendEnvironment($environment, $config);
|
||||
|
||||
$environment->addBlockRenderer('FencedCode', new FencedCodeRenderer());
|
||||
|
||||
$environment->addDocumentProcessor(new TOC\Processor($config));
|
||||
$environment->addBlockRenderer('Todaymade\Daux\ContentTypes\Markdown\TableOfContents', new TOC\Renderer($config));
|
||||
}
|
||||
|
70
libs/Format/HTML/ContentTypes/Markdown/FencedCodeRenderer.php
Normale Datei
70
libs/Format/HTML/ContentTypes/Markdown/FencedCodeRenderer.php
Normale Datei
@ -0,0 +1,70 @@
|
||||
<?php namespace Todaymade\Daux\Format\HTML\ContentTypes\Markdown;
|
||||
|
||||
use Highlight\Highlighter;
|
||||
use League\CommonMark\Block\Element\AbstractBlock;
|
||||
use League\CommonMark\Block\Element\FencedCode;
|
||||
use League\CommonMark\Block\Renderer\BlockRendererInterface;
|
||||
use League\CommonMark\ElementRendererInterface;
|
||||
use League\CommonMark\HtmlElement;
|
||||
use League\CommonMark\Util\Xml;
|
||||
|
||||
class FencedCodeRenderer implements BlockRendererInterface
|
||||
{
|
||||
function __construct() {
|
||||
$this->hl = new Highlighter();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractBlock $block
|
||||
* @param HtmlRendererInterface $htmlRenderer
|
||||
* @param bool $inTightList
|
||||
*
|
||||
* @return HtmlElement|string
|
||||
*/
|
||||
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, $inTightList = false)
|
||||
{
|
||||
if (!($block instanceof FencedCode)) {
|
||||
throw new \InvalidArgumentException('Incompatible block type: ' . get_class($block));
|
||||
}
|
||||
|
||||
$attrs = [];
|
||||
foreach ($block->getData('attributes', []) as $key => $value) {
|
||||
$attrs[$key] = Xml::escape($value);
|
||||
}
|
||||
|
||||
$content = $block->getStringContent();
|
||||
|
||||
$language = $this->getLanguage($block->getInfoWords());
|
||||
$highlighted = false;
|
||||
if ($language) {
|
||||
$attrs['class'] = isset($attrs['class']) ? $attrs['class'] . ' ' : '';
|
||||
|
||||
try {
|
||||
$highlighted = $this->hl->highlight($language, $content);
|
||||
$content = $highlighted->value;
|
||||
$attrs['class'] .= 'hljs ' . $highlighted->language;
|
||||
} catch (Exception $e) {
|
||||
$attrs['class'] .= 'language-' . $language;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$highlighted) {
|
||||
$content = Xml::escape($content);
|
||||
}
|
||||
|
||||
return new HtmlElement(
|
||||
'pre',
|
||||
[],
|
||||
new HtmlElement('code', $attrs, $content)
|
||||
);
|
||||
}
|
||||
|
||||
public function getLanguage($infoWords)
|
||||
{
|
||||
if (count($infoWords) === 0 || strlen($infoWords[0]) === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Xml::escape($infoWords[0], true);
|
||||
}
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren