使用hightlight.js标记代码颜色并拓展显示行号

首页 编程分享 JQUERY丨JS丨VUE 正文

袅袅牧童 推荐 原创 编程分享 2016-03-26 09:09:37

简介 最近真心觉得layer内置的代码编辑器死气沉沉且没有可读性,google了一下,发现真的有款不错的代码编辑器,就是这个,美中不足的是没有行号显示,在网上找了扩展类,又编辑了下发现好多了,分享下。


先看看效果图吧:


搜嘎 pretty good,right?别着急,我们开始 。。。

首先下载highlight.js:

官网在此,直接download:https://highlightjs.org/ 

官网下载页面默认的语言选择基本涵盖了主流语言应用,当然如果你有特殊需要自己勾选下载  。。。

引入highlight应用:

<link rel="stylesheet" href="/code/styles/vs2015.css" rel="external nofollow" rel="external nofollow" >
<script src="/code/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

需求的类型:

highlight 初始化要求代码区需要的格式是: <pre><code>    ......here is your codes.........     </code></pre>

需求的style 可以在下载的style文件夹里自己选定类型。

ok,如果你操作无误,现在基本可以看到代码高亮显示了。

添加代码行号显示插件:

<script src="/code/line-number.js"></script> //引用line-number类库
<script>hljs.initHighlightingOnLoad();hljs.initLineNumbersOnLoad();</script> //启动line-number;

特别注意:

有时候浏览器会渲染html代码块,解决方案:

1. 将< >转为&lt; &gt; 
2. 使用如下代码: 

var aa = $('.con_text').find('pre'), var len = aa.length;
for( i in aa){
aa[i].innerText = aa[i].innerHTML; //避开浏览器直接渲染代码块;
}

这里是一个博主命名line-number.js的文件 ,拷贝下文代码,添加引用到 highlight.pack.js 文件引用之后,再添加 line-number的启动函数,如下:

/**
line-number的代码,直接拷贝吧:


 * add line number for heighlightjs
 * discover on webset
 * 2017.5.18
 * update 2018.12.19
 */
(function (w, d) {

    var TABLE_NAME = 'hljs-ln',
        LINE_NAME = 'hljs-ln-line',
        CODE_BLOCK_NAME = 'hljs-ln-code',
        NUMBERS_BLOCK_NAME = 'hljs-ln-numbers',
        NUMBER_LINE_NAME = 'hljs-ln-n',
        DATA_ATTR_NAME = 'data-line-number',
        BREAK_LINE_REGEXP = /\r\n|\r|\n|<br>|<br\/>/g;

    if (w.hljs) {
        w.hljs.initLineNumbersOnLoad = initLineNumbersOnLoad;
        w.hljs.lineNumbersBlock = lineNumbersBlock;
        w.hljs.lineNumbersValue = lineNumbersValue;

        addStyles();
    } else {
        w.console.error('highlight.js not detected!');
    }

    function addStyles () {
        var css = d.createElement('style');
        css.type = 'text/css';
        css.innerHTML = format(
            '.{0}{border-collapse:collapse}' +
            '.{0} td{padding:0}' +
            '.{1}:before{content:attr({2})}',
        [
            TABLE_NAME,
            NUMBER_LINE_NAME,
            DATA_ATTR_NAME
        ]);
        d.getElementsByTagName('head')[0].appendChild(css);
    }

    function initLineNumbersOnLoad (options) {
        if (d.readyState === 'interactive' || d.readyState === 'complete') {
            documentReady(options);
        } else {
            w.addEventListener('DOMContentLoaded', function () {
                documentReady(options);
            });
        }
    }

    function documentReady (options) {
        try {
            var blocks = d.querySelectorAll('code.hljs,code.nohighlight');

            for (var i in blocks) {
                if (blocks.hasOwnProperty(i)) {
                    lineNumbersBlock(blocks[i], options);
                }
            }
        } catch (e) {
            w.console.error('LineNumbers error: ', e);
        }
    }

    function lineNumbersBlock (element, options) {
        if (typeof element !== 'object') return;

        async(function () {
            element.innerHTML = lineNumbersInternal(element, options);
        });
    }

    function lineNumbersValue (value, options) {
        if (typeof value !== 'string') return;

        var element = document.createElement('code')
        element.innerHTML = value

        return lineNumbersInternal(element, options);
    }

    function lineNumbersInternal (element, options) {
        // define options or set default
        options = options || {
            singleLine: false
        };

        // convert options
        var firstLineIndex = !!options.singleLine ? 0 : 1;

        duplicateMultilineNodes(element);

        return addLineNumbersBlockFor(element.innerHTML, firstLineIndex);
    }

    function addLineNumbersBlockFor (inputHtml, firstLineIndex) {

        var lines = getLines(inputHtml);
        if (inputHtml.trim().length == 0) { return ''; }

        // if last lines contains only carriage return remove it
        for (ii = lines.length - 1; ii > 0; ii--) {
             if (lines[ii].trim() === '') {
                    lines.pop();
             } else {
                    break;
             } 
        }      
        if (lines.length >= firstLineIndex) {
            var html = '';
            for (var i = 0, l = lines.length; i < l; i++) {
                var c = i <= 9 ? '0' + i + '.' : i + '.'; //change linenumber style;
                html += format(

'<tr>' +

'<td class="{0}">' +
'<div class="{1} {2}" {3}="{5}"></div>' +
'</td>' +
'<td class="{4}">' +
'<div class="{1}">{6}</div>' +
'</td>' +
'</tr>',
[ NUMBERS_BLOCK_NAME, LINE_NAME, NUMBER_LINE_NAME, DATA_ATTR_NAME, CODE_BLOCK_NAME, c, lines[i].length > 0 ? lines[i] : ' ' ]); }

return format('<table class="{0}">{1}</table>', [ TABLE_NAME, html ]);

} return inputHtml; } /** * Recursive method for fix multi-line elements implementation in highlight.js * Doing deep passage on child nodes. * @param {HTMLElement} element */ function duplicateMultilineNodes (element) { var nodes = element.childNodes; for (var node in nodes) { if (nodes.hasOwnProperty(node)) { var child = nodes[node]; if (getLinesCount(child.textContent) > 0) { if (child.childNodes.length > 0) { duplicateMultilineNodes(child); } else { duplicateMultilineNode(child.parentNode); } } } } } /** * Method for fix multi-line elements implementation in highlight.js * @param {HTMLElement} element */ function duplicateMultilineNode (element) { var className = element.className; if ( ! /hljs-/.test(className)) return; var lines = getLines(element.innerHTML); for (var i = 0, result = ''; i < lines.length; i++) { var lineText = lines[i].length > 0 ? lines[i] : ' '; result += format('{1}\n', [ className, lineText ]); } element.innerHTML = result.trim(); } function getLines (text) { if (text.length === 0) return []; return text.split(BREAK_LINE_REGEXP); } function getLinesCount (text) { return (text.trim().match(BREAK_LINE_REGEXP) || []).length; } function async (func) { w.setTimeout(func, 0); } /** * {@link https://wcoder.github.io/notes/string-format-for-string-formating-in-javascript} * @param {string} format * @param {array} args */ function format (format, args) { return format.replace(/\{(\d+)\}/g, function(m, n){ return args[n] ? args[n] : m; }); } }(window, document));



Tags:


本篇评论 —— 揽流光,涤眉霜,清露烈酒一口话苍茫。


    声明:参照站内规则,不文明言论将会删除,谢谢合作。


      最新评论




ABOUT ME

Blogger:袅袅牧童 | Arkin

Ido:PHP攻城狮

WeChat:nnmutong

Email:nnmutong@icloud.com

标签云