highlight.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. var each = require('./each');
  2. var defaults = require('./defaults');
  3. exports = function(str) {
  4. var lang =
  5. arguments.length > 1 && arguments[1] !== undefined
  6. ? arguments[1]
  7. : 'js';
  8. var style =
  9. arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  10. defaults(style, defStyle);
  11. str = str.replace(/</g, '&lt;').replace(/>/g, '&gt;');
  12. lang = language[lang];
  13. var subLangSi = 0;
  14. var subLangs = [];
  15. each(lang, function(val) {
  16. if (!val.language) return;
  17. str = str.replace(val.re, function($1, $2) {
  18. if (!$2) {
  19. return $1;
  20. }
  21. subLangs[subLangSi++] = exports($2, val.language, style);
  22. return $1.replace($2, '___subtmpl' + (subLangSi - 1) + '___');
  23. });
  24. });
  25. each(lang, function(val, key) {
  26. if (language[val.language]) return;
  27. str = str.replace(val.re, '___' + key + '___$1___end' + key + '___');
  28. });
  29. var levels = [];
  30. str = str.replace(/___(?!subtmpl)\w+?___/g, function($0) {
  31. var end = $0.substr(3, 3) === 'end',
  32. tag = (!end ? $0.substr(3) : $0.substr(6)).replace(/_/g, ''),
  33. lastTag = levels.length > 0 ? levels[levels.length - 1] : null;
  34. if (
  35. !end &&
  36. (lastTag == null ||
  37. tag == lastTag ||
  38. (lastTag != null &&
  39. lang[lastTag] &&
  40. lang[lastTag].embed != undefined &&
  41. lang[lastTag].embed.indexOf(tag) > -1))
  42. ) {
  43. levels.push(tag);
  44. return $0;
  45. } else if (end && tag == lastTag) {
  46. levels.pop();
  47. return $0;
  48. }
  49. return '';
  50. });
  51. each(lang, function(val, key) {
  52. var s = style[val.style]
  53. ? ' style="'.concat(style[val.style], '"')
  54. : '';
  55. str = str
  56. .replace(new RegExp('___end' + key + '___', 'g'), '</span>')
  57. .replace(
  58. new RegExp('___' + key + '___', 'g'),
  59. '<span class="'.concat(val.style, '"').concat(s, '>')
  60. );
  61. });
  62. each(lang, function(val) {
  63. if (!val.language) return;
  64. str = str.replace(/___subtmpl\d+___/g, function($tmpl) {
  65. var i = parseInt($tmpl.replace(/___subtmpl(\d+)___/, '$1'), 10);
  66. return subLangs[i];
  67. });
  68. });
  69. return str;
  70. };
  71. var defStyle = {
  72. comment: 'color:#63a35c;',
  73. string: 'color:#183691;',
  74. number: 'color:#0086b3;',
  75. keyword: 'color:#a71d5d;',
  76. operator: 'color:#994500;'
  77. };
  78. var language = {};
  79. language.js = {
  80. comment: {
  81. re: /(\/\/.*|\/\*([\s\S]*?)\*\/)/g,
  82. style: 'comment'
  83. },
  84. string: {
  85. re: /(('.*?')|(".*?"))/g,
  86. style: 'string'
  87. },
  88. numbers: {
  89. re: /(-?(\d+|\d+\.\d+|\.\d+))/g,
  90. style: 'number'
  91. },
  92. keywords: {
  93. re: /(?:\b)(function|for|foreach|while|if|else|elseif|switch|break|as|return|this|class|self|default|var|const|let|false|true|null|undefined)(?:\b)/gi,
  94. style: 'keyword'
  95. },
  96. operator: {
  97. re: /(\+|-|\/|\*|%|=|&lt;|&gt;|\||\?|\.)/g,
  98. style: 'operator'
  99. }
  100. };
  101. language.html = {
  102. comment: {
  103. re: /(&lt;!--([\s\S]*?)--&gt;)/g,
  104. style: 'comment'
  105. },
  106. tag: {
  107. re: /(&lt;\/?\w(.|\n)*?\/?&gt;)/g,
  108. style: 'keyword',
  109. embed: ['string']
  110. },
  111. string: language.js.string,
  112. css: {
  113. re: /(?:&lt;style.*?&gt;)([\s\S]*)?(?:&lt;\/style&gt;)/gi,
  114. language: 'css'
  115. },
  116. script: {
  117. re: /(?:&lt;script.*?&gt;)([\s\S]*?)(?:&lt;\/script&gt;)/gi,
  118. language: 'js'
  119. }
  120. };
  121. language.css = {
  122. comment: language.js.comment,
  123. string: language.js.string,
  124. numbers: {
  125. re: /((-?(\d+|\d+\.\d+|\.\d+)(%|px|em|pt|in)?)|#[0-9a-fA-F]{3}[0-9a-fA-F]{3})/g,
  126. style: 'number'
  127. },
  128. keywords: {
  129. re: /(@\w+|:?:\w+|[a-z-]+:)/g,
  130. style: 'keyword'
  131. }
  132. };
  133. module.exports = exports;