weixin_39702639
weixin_39702639
2020-12-29 15:22

自动引入prismjs相关语言组件的功能

目前插件设置里面只有引入了默认的4种prismjs语言组件,如果需要高亮其他的语言,还得去官网生成后放到某个地方来引用,比较麻烦,我写了一段根据文章内容自动检测用到哪些语言,自动引用相关语言组件的代码。你看下,如果觉得可以的话,可以合并到插件里面,可以提供一个选项来开关这个功能。

php
class prism_js {

    public $languages = array();

    public $languages_all = array(
        "markup" => "Markup",
        "css" => "CSS",
        "clike" => "C-like",
        "javascript" => "JavaScript",
        "abap" => "ABAP",
        "actionscript" => "ActionScript",
        "ada" => "Ada",
        "apacheconf" => "Apache Configuration",
        "apl" => "APL",
        "applescript" => "AppleScript",
        "asciidoc" => "AsciiDoc",
        "aspnet" => "ASP.NET (C#)",
        "autoit" => "AutoIt",
        "autohotkey" => "AutoHotkey",
        "bash" => "Bash",
        "basic" => "BASIC",
        "batch" => "Batch",
        "bison" => "Bison",
        "brainfuck" => "Brainfuck",
        "bro" => "Bro",
        "c" => "C",
        "csharp" => "C#",
        "cpp" => "C++",
        "coffeescript" => "CoffeeScript",
        "crystal" => "Crystal",
        "css-extras" => "CSS Extras",
        "d" => "D",
        "dart" => "Dart",
        "django" => "Django/Jinja2",
        "diff" => "Diff",
        "docker" => "Docker",
        "eiffel" => "Eiffel",
        "elixir" => "Elixir",
        "erlang" => "Erlang",
        "fsharp" => "F#",
        "fortran" => "Fortran",
        "gherkin" => "Gherkin",
        "git" => "Git",
        "glsl" => "GLSL",
        "go" => "Go",
        "graphql" => "GraphQL",
        "groovy" => "Groovy",
        "haml" => "Haml",
        "handlebars" => "Handlebars",
        "haskell" => "Haskell",
        "haxe" => "Haxe",
        "http" => "HTTP",
        "icon" => "Icon",
        "inform7" => "Inform 7",
        "ini" => "Ini",
        "j" => "J",
        "jade" => "Jade",
        "java" => "Java",
        "jolie" => "Jolie",
        "json" => "JSON",
        "julia" => "Julia",
        "keyman" => "Keyman",
        "kotlin" => "Kotlin",
        "latex" => "LaTeX",
        "less" => "Less",
        "livescript" => "LiveScript",
        "lolcode" => "LOLCODE",
        "lua" => "Lua",
        "makefile" => "Makefile",
        "markdown" => "Markdown",
        "matlab" => "MATLAB",
        "mel" => "MEL",
        "mizar" => "Mizar",
        "monkey" => "Monkey",
        "nasm" => "NASM",
        "nginx" => "nginx",
        "nim" => "Nim",
        "nix" => "Nix",
        "nsis" => "NSIS",
        "objectivec" => "Objective-C",
        "ocaml" => "OCaml",
        "oz" => "Oz",
        "parigp" => "PARI/GP",
        "parser" => "Parser",
        "pascal" => "Pascal",
        "perl" => "Perl",
        "php" => "PHP",
        "php-extras" => "PHP Extras",
        "powershell" => "PowerShell",
        "processing" => "Processing",
        "prolog" => "Prolog",
        "properties" => ".properties",
        "protobuf" => "Protocol Buffers",
        "puppet" => "Puppet",
        "pure" => "Pure",
        "python" => "Python",
        "q" => "Q",
        "qore" => "Qore",
        "r" => "R",
        "jsx" => "React JSX",
        "reason" => "Reason",
        "rest" => "reST (reStructuredText)",
        "rip" => "Rip",
        "roboconf" => "Roboconf",
        "ruby" => "Ruby",
        "rust" => "Rust",
        "sas" => "SAS",
        "sass" => "Sass (Sass)",
        "scss" => "Sass (Scss)",
        "scala" => "Scala",
        "scheme" => "Scheme",
        "smalltalk" => "Smalltalk",
        "smarty" => "Smarty",
        "sql" => "SQL",
        "stylus" => "Stylus",
        "swift" => "Swift",
        "tcl" => "Tcl",
        "textile" => "Textile",
        "twig" => "Twig",
        "typescript" => "TypeScript",
        "vbnet" => "VB.Net",
        "verilog" => "Verilog",
        "vhdl" => "VHDL",
        "vim" => "vim",
        "wiki" => "Wiki markup",
        "xojo" => "Xojo (REALbasic)",
        "yaml" => "YAML"
    );

    public $languages_default = array(
        "markup" => "Markup",
        "css" => "CSS",
        "clike" => "C-like",
        "javascript" => "JavaScript",
    );

    public $prism_base_url = 'https://cdn.bootcss.com/prism/1.6.0';

    public $prism_theme = 'default';

    public $prism_plugins = array();

    public function __construct() {
        add_filter('the_content', array($this, 'prism_languages'));
        add_action('wp_footer', array($this, 'prism_styles_scripts'));
    }

    public function prism_languages($content) {
        if (preg_match_all('/<code class="language-([a-z\-0-9]+)"> 0 && !empty($language_matches[1])) {
            foreach ($language_matches[1] as $language_match) {
                if (isset($this->languages_all[$language_match])) {
                    $this->languages[$language_match] = $this->languages_all[$language_match];
                }
            }
        }
        return $content;
    }

    public function prism_styles_scripts() {
        $prism_styles = array();
        $prism_scripts = array();

        if (!empty($this->languages)) {
            if (count($this->languages) <= count($this->languages_default)) {
                $use_default = true;
                foreach ($this->languages as $language => $display_name) {
                    if (!array_key_exists($language, $this->languages_default)) {
                        $use_default = false;
                        break;
                    }
                }
            } else {
                $use_default = false;
            }
            if ($use_default) {
                $prism_scripts[] = "{$this->prism_base_url}/prism.min.js";
            } else {
                $prism_scripts[] = "{$this->prism_base_url}/components/prism-core.min.js";
                foreach ($this->languages as $language => $display_name) {
                    $prism_scripts[] = "{$this->prism_base_url}/components/prism-{$language}.min.js";
                }
            }
            foreach ($this->prism_plugins as $prism_plugin => $prism_plugin_config) {
                if ($prism_plugin_config['css'] === true) {
                    $prism_styles[] = "{$this->prism_base_url}/plugins/{$prism_plugin}/prism-{$prism_plugin}.min.css";
                }
                if ($prism_plugin_config['js'] === true) {
                    $prism_scripts[] = "{$this->prism_base_url}/plugins/{$prism_plugin}/prism-{$prism_plugin}.min.js";
                }
            }
            if (empty($this->prism_theme) || $this->prism_theme == 'default') {
                $prism_styles[] = "{$this->prism_base_url}/themes/prism.min.css";
            } else {
                $prism_styles[] = "{$this->prism_base_url}/themes/prism-{$this->prism_theme}.min.css";
            }
        }

        foreach ($prism_styles as $prism_style) {
            echo '<link rel="stylesheet" type="text/css" href="'%20.%20%24prism_style%20.%20'">';
        }

        foreach ($prism_scripts as $prism_script) {
            echo '<script type="text/javascript" src="'%20.%20%24prism_script%20.%20'"></script>';
        }
    }
}

该提问来源于开源项目:LuRenJiasWorld/WP-Editor.md

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

10条回答

  • weixin_39600823 weixin_39600823 4月前

    ~~呃,关于那个依赖,如果是js好说,问题php我就半吊子技术...不会啊~~

    好吧,摸索出来了,F12查看源代码也看到依赖文件加载出来了,可是还是报错,看了下不知道是不是加载顺序问题...感觉和这个没关系吧?

    代码如下:

    php
        public $components = [
            "java" => [
                "title"   => "Java",
                "require" => "clike",
                "owner"   => "sherblot"
            ],
            "php" => [
                "title"   => "PHP",
                "require" => "clike",
                "owner"   => "milesj"
            ],
            "less" => [
                "title"   => "Less",
                "require" => "css",
                "owner"   => "Golmote"
            ]
        ];
    
    php
                if ($use_default) {
                    $prism_scripts[] = $prism_base_url . "/prism.min.js";
                } else {
                    $prism_scripts[] = $prism_base_url . "/components/prism-core.min.js";
                    foreach ($this->languages as $language => $display_name) {
                        $prism_scripts[] = $prism_base_url . "/components/prism-{$language}.min.js";
                        //循环遍历引入依赖脚本文件
                        foreach ( $this->components as $components => $components_req ) {
                            if ( $components === $language ) {
                                $require = $components_req['require'];
                                $prism_scripts[] = $prism_base_url . "/components/prism-{$require}.min.js";
                            }
                        }
                    }
                }
    
    点赞 评论 复制链接分享
  • weixin_39788969 weixin_39788969 4月前

    我 PR 了,把 JS Object 改成 PHP Array 累死我了。 这个和加载顺序有关的

    点赞 评论 复制链接分享
  • weixin_39600823 weixin_39600823 4月前

    蛤蛤,谢谢了。

    点赞 评论 复制链接分享
  • weixin_39788969 weixin_39788969 4月前

    这个功能不错!按需加载对应样式

    另外如果 base url 改成可配置就更好了

    点赞 评论 复制链接分享
  • weixin_39702639 weixin_39702639 4月前

    是的,这个只是一个原型,要加到项目里面需要修改下配置页,可以配置base url和加载那些插件

    点赞 评论 复制链接分享
  • weixin_39600823 weixin_39600823 4月前

    已实现功能,详见提交日志

    点赞 评论 复制链接分享
  • weixin_39600823 weixin_39600823 4月前

    貌似有几个问题: 第一引入插件,比如line Number 行数插件,带入数组不显示,js和css没加载进来。

    php
    public $prism_plugins = array(
            "line-numbers" => "Line Numbers"
        );
    

    如果是强写插件资源位置倒没啥问题。

    第二是渲染某些语言高亮加载失败,比如渲染php在控制台报错:

    javascript
    Uncaught TypeError: Cannot set property 'keyword' of undefined
        at Object.extend (prism-core.min.js:1)
        at prism-php.min.js:1
    

    好吧,只要是$languages_all数组里面的语法基本都报上面的错,原因不知

    点赞 评论 复制链接分享
  • weixin_39788969 weixin_39788969 4月前

    各个组件之间存在依赖关系,PHP 依赖 C-like。事实上很多都依赖默认的语言。

    在这里可以查看依赖 https://github.com/PrismJS/prism/blob/gh-pages/components.js

    (要把这些代码转换成 PHP 可是体力活啊

    点赞 评论 复制链接分享
  • weixin_39600823 weixin_39600823 4月前

    那我Java高亮也错...也不会依赖啥吧...

    点赞 评论 复制链接分享
  • weixin_39788969 weixin_39788969 4月前

    Java 也依赖 C-like

    还有,看了一下代码,插件应该是这样设置的。

     php
        public $prism_plugins = array(
            "line-numbers" => array (
                "js" => true,
                "css" => true
            )
        );
    

    这样虽然能引入,但是不显示行数,~~原因未知~~找到原因了

    line-numbers.min.cssprism.min.css 先加载了,导致部分属性被覆盖

    点赞 评论 复制链接分享

相关推荐