kadet/keylighter

PHP的另一个语法高亮器


README

Logo

Packagist GitHub Actions GitHub Actions Try it

stability: stable stability: unstable

PHP中又一个旨在尽可能扩展性强且易于使用的语法高亮器,但同时也考虑了性能。

您可以在https://keylighter.kadet.net/上使用最新版本进行实时尝试。

名称

名称“KeyLighter”灵感来源于摄影和电影中的“主光”概念。

主光是摄影师、电影摄影师、灯光摄像师或其他场景创作者在灯光设置中首先使用且通常最重要的光。主光的作用是突出主题的形状和维度。

KeyLighter应该做同样的事情——针对代码。

安装

$ composer require kadet/keylighter

要使用 KeyLighter,您只需要PHP 7.3或更高版本,不需要特殊的扩展。

全局安装

可以将 KeyLighter 作为全局Composer库安装

$ composer global require kadet/keylighter

然后您可以使用内置的简单命令行高亮应用程序

$ keylighter [command = highlight] [-l|--language [LANGUAGE]] [-f|--format [FORMAT]] [-d|--debug [DEBUG]] [--]  <path>...

如果您想将内容输入到 KeyLighter 中,只需指定路径为 php://stdin。您可以使用 list 命令查看所有可用命令,并使用 --help 参数获取详细帮助。您无需明确指定 highlight 命令。

PowerShell

您在Windows上使用PowerShell?太棒了!KeyLighter 附带集成PowerShell模块,使命令行使用更加出色。只需导入模块(例如在配置文件中),然后您就可以开始使用了。

PS> Import-Module "${env:APPDATA}\Composer\vendor\kadet\keylighter\bin\KeyLighter.psd1"

要使用自动完成功能,您需要PowerShell v5(随Windows 10提供)或安装TabExpansion++模块。

Powershell Support

为什么选择KeyLighter?

易于使用

use Kadet\Highlighter\Language;

echo \Kadet\Highlighter\highlight($source, new Language\Php(), $formatter);
// or
echo \Kadet\Highlighter\KeyLighter::get()->highlight($source, new Language\Php(), $formatter);
// or
$keylighter = new \Kadet\Highlighter\KeyLighter([options]);
echo $keylighter->highlight($source, new Language\Php(), $formatter);

您可以在此处找到所有可用的语言,并在此处找到格式化程序。

它可以在CLI上工作!不仅如此!

KeyLighter最初是为我的个人使用设计的CLI高亮器,但我后来决定它应该能够生成任何可能的输出,目前支持

Cli \Kadet\Highlighter\Formatter\CliFormatter

CLI

它甚至可以样式化,默认样式存储在Styles\Cli\Default.php中,但您也可以将额外的参数传递给构造函数

new \Kadet\Highlighter\Formatter\CliFormatter([
    'string'      => ['color' => 'green'],
    'keyword'     => ['color' => 'yellow'],
    ...
])

HTML \Kadet\Highlighter\Formatter\HtmlFormatter

HTML

每个标记都放置在其自己的span中,并且类名前缀化,这样就可以很容易地用CSS进行样式化,并且不应该与您现有的任何类冲突

<span class="kl-variable">$maxOption</span>
pre > span.kl-variable { color: #F7750D; }

您的?

编写您自己的格式化程序非常简单。文档即将推出。

上下文感知

某些标记在某些上下文中有效,而在其他上下文中则无效。这个库是上下文感知的,并且您可以定义它们何时有效。

在这种情况下,上下文只是“在其他标记内部”,例如,假设string标记被定义为从“”到下一个“”之间的所有内容,而keyword被定义为子串'sit'。

 string:start      keyword:start
"Lorem ipsum dolor sit amtet"
         keyword:end        string:end

Token tree:

Token.name           Token.pos
------------------------------
string:start         0
    keyword:start    21
    keyword:end      23
string:end           30

所以如您所见,keywordstring内部,因此它是不有效的,应该被删除。您可以定义仅在特定上下文中有效的标记,或在其他上下文中无效的标记。

哦,标记名称是级联的,这意味着string.singlestring,但string必然不是string.single

轻松编写您自己的语言定义

您可以轻松地通过新的语言扩展KeyLighter,更详细的文档即将推出。

例如,XML的定义如下所示

class Xml extends GreedyLanguage
{
    private const IDENTIFIER = '(?P<namespace>[\w\.-]+:)?(?P<name>[\w\.-]+)';

    /**
     * Tokenization rules
     */
    public function setupRules()
    {
        $this->rules->addMany([
            'tag.open'  => [
                new OpenRule(new RegexMatcher('/(<[\w\.-]+)[:\/>:\s]/')),
                new CloseRule(new SubStringMatcher('>'), ['context' => ['!string', '!comment']])
            ],
            'tag.close' => new Rule(new RegexMatcher('/(<\/' . self::IDENTIFIER . '>)/')),

            'symbol.tag' => new Rule(new RegexMatcher('/<\\/?' . self::IDENTIFIER . '/', [
                'name'      => Token::NAME,
                'namespace' => '$.namespace'
            ]), ['context' => ['tag', '!string']]),

            'symbol.attribute' => new Rule(new RegexMatcher('/' . self::IDENTIFIER . '=/', [
                'name'      => Token::NAME,
                'namespace' => '$.namespace'
            ]), ['context' => ['tag', '!string']]),

            'constant.entity' => new Rule(new RegexMatcher('/(&(?:\#\d+|[a-z])+;)/si')),

            'comment' => new Rule(new CommentMatcher(null, [['<!--', '-->']])),
            'string'  => CommonFeatures::strings(['single' => '\'', 'double' => '"'], ['context' => ['tag']]),
        ]);
    }

    /** {@inheritdoc} */
    public function getIdentifier()
    {
        return 'xml';
    }

    public static function getMetadata()
    {
        return [
            'name'      => ['xml'],
            'mime'      => ['application/xml', 'text/xml'],
            'extension' => ['*.xml']
        ];
    }
}

我会尽量写出尽可能多的定义,但任何Pull Request(PR)都受欢迎。

嵌入式语言

许多语言可以同时使用,例如在html中嵌入cssjs,在php中使用sql等。
php等等。 KeyLighter可以无任何问题地处理和突出显示嵌入式语言。

Embedded languages

快速

尽管它并非PHP中最快的代码高亮器,但它仍然相当快,比GeSHi快2倍以上。

测试

KeyLighter使用phpunit进行测试

$ ./vendor/bin/phpunit

路线图

还有一些事情要做,你可以在trello上找到所有内容。

贡献

有关详细信息,请参阅CONTRIBUTING.md

感谢

感谢MaciejMaciej和Monika的所有支持,包括精神上的支持。