wcoder / highlightjs-line-numbers.js

Line numbering plugin for Highlight.js
https://wcoder.github.io/highlightjs-line-numbers.js/
MIT License
548 stars 126 forks source link

How to use it with typescript and webpack #19

Closed pnowy closed 7 years ago

pnowy commented 7 years ago

Hi,

I'm using the highlight.js with the typecscript and webpack by import (and @types for it):

import * as hljs from 'highlight.js';

I'm trying to import also the line-numbers after it but this approach doesn't work. Do you have any suggestion how to deal with the problem?

Thanks

wcoder commented 7 years ago

Thanks for use this plugin!

Currently, this plugin don't have type definitions .d.ts file for TypeSctipt.

pnowy commented 7 years ago

I wrote some replacement based on you code - hope that not a problem ;) I put it here - might someone find it useful.


// based on the https://github.com/wcoder/highlightjs-line-numbers.js by @wcoder
export class HighlightJsLineNumbers {

    public static readonly TABLE_NAME: string = 'hljs-ln';
    public static readonly LINE_NAME: string = 'hljs-ln-line';
    public static readonly CODE_BLOCK_NAME: string = 'hljs-ln-code';
    public static readonly NUMBERS_BLOCK_NAME: string = 'hljs-ln-numbers';
    public static readonly NUMBER_LINE_NAME: string = 'hljs-ln-n';
    public static readonly DATA_ATTR_NAME: string = 'data-line-number';

    public static format(str, args) {
        return str.replace(/\{(\d+)\}/g, function(m, n) {
            return args[n] ? args[n] : m;
        });
    };

    public static lineNumbersBlock(element, options?: any) {
        if (typeof element !== 'object') {
            return;
        }

        // define options or set default
        options = options || {
            singleLine: true // enable plugin for code block with one line
        };

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

        const lines = this.getLines(element.innerHTML);
        if (lines.length > firstLineIndex) {
            let html = '';

            let i = 0;
            const l = lines.length;
            console.log(l)
            for (; i < l; i++) {
                html += this.format(
                    '<tr><td class="{0}"><div class="{1} {2}" {3}="{5}"></div></td><td class="{4}"><div class="{1}">{6}</div></td></tr>',
                    [
                        this.NUMBERS_BLOCK_NAME, this.LINE_NAME, this.NUMBER_LINE_NAME, this.DATA_ATTR_NAME, this.CODE_BLOCK_NAME,
                        i + 1,
                        lines[i].length > 0 ? lines[i] : ' '
                    ]);
            }

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

    public static getLines(text) {
        if (text.length === 0) {
            return [];
        }
        const lines = text.split(/\r\n|\r|\n/g);
        // if last line contains only carriage return remove it
        if (_.trim(_.last(lines)) === '') {
            lines.pop();
        }
        return lines;
    }

}

Styles (SCSS):

    // highlight-js line numbers styles
    .hljs-ln {
        border-collapse: collapse;
        td {
            padding: 0;
        }

        /* for block of numbers */
        td.hljs-ln-numbers {
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;

            text-align: center;
            border-right: 1px solid #717171;
            vertical-align: top;
            padding-right: 5px;
        }

        /* for block of code */
        td.hljs-ln-code {
            padding-left: 10px;
        }
    }

    .hljs-ln-n:before {
        content: attr(data-line-number)
    }

And usage:

HighlightJsLineNumbers.lineNumbersBlock(node);

pnowy commented 7 years ago

PS. The following part:

if (_.trim(_.last(lines)) === '') {
            lines.pop();
        }

is using lodash.