You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.3 KiB

  1. (function (w) {
  2. 'use strict';
  3. var TABLE_NAME = 'hljs-ln',
  4. LINE_NAME = 'hljs-ln-line',
  5. CODE_BLOCK_NAME = 'hljs-ln-code',
  6. NUMBERS_BLOCK_NAME = 'hljs-ln-numbers',
  7. NUMBER_LINE_NAME = 'hljs-ln-n',
  8. DATA_ATTR_NAME = 'data-line-number';
  9. // https://wcoder.github.io/notes/string-format-for-string-formating-in-javascript
  10. String.prototype.format = String.prototype.f = function () {
  11. var args = arguments;
  12. return this.replace(/\{(\d+)\}/g, function(m, n){
  13. return args[n] ? args[n] : m;
  14. });
  15. };
  16. if (typeof w.hljs === 'undefined') {
  17. console.error('highlight.js not detected!');
  18. } else {
  19. w.hljs.initLineNumbersOnLoad = initLineNumbersOnLoad;
  20. w.hljs.lineNumbersBlock = lineNumbersBlock;
  21. addStyles();
  22. }
  23. function addStyles () {
  24. var css = document.createElement('style');
  25. css.type = 'text/css';
  26. css.innerHTML = ('.{0}{border-collapse:collapse}' +
  27. '.{0} td{padding:0}' +
  28. '.{1}:before{content:attr({2})}').format(TABLE_NAME, NUMBER_LINE_NAME, DATA_ATTR_NAME);
  29. document.getElementsByTagName('head')[0].appendChild(css);
  30. }
  31. function initLineNumbersOnLoad () {
  32. if (document.readyState === 'complete') {
  33. documentReady();
  34. } else {
  35. w.addEventListener('DOMContentLoaded', documentReady);
  36. }
  37. }
  38. function documentReady () {
  39. try {
  40. var blocks = document.querySelectorAll('code.hljs');
  41. for (var i in blocks) {
  42. if (blocks.hasOwnProperty(i)) {
  43. lineNumbersBlock(blocks[i]);
  44. }
  45. }
  46. } catch (e) {
  47. console.error('LineNumbers error: ', e);
  48. }
  49. }
  50. function lineNumbersBlock (element) {
  51. if (typeof element !== 'object') return;
  52. var lines = getLines(element.innerHTML);
  53. if (lines.length > 1) {
  54. var html = '';
  55. for (var i = 0; i < lines.length; i++) {
  56. html += ('<tr><td class="{0}"><div class="{1} {2}" {3}="{5}"></div></td>' +
  57. '<td class="{4}"><div class="{1}">{6}</div></td></tr>').format(
  58. NUMBERS_BLOCK_NAME,
  59. LINE_NAME,
  60. NUMBER_LINE_NAME,
  61. DATA_ATTR_NAME,
  62. CODE_BLOCK_NAME,
  63. i + 1,
  64. lines[i].length > 0 ? lines[i] : ' ');
  65. }
  66. element.innerHTML = '<table class="{0}">{1}</table>'.format(TABLE_NAME, html);
  67. }
  68. }
  69. function getLines(text) {
  70. if (text.length === 0) return [];
  71. return text.split(/\r\n|\r|\n/g);
  72. }
  73. }(window));