markdown.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. Language: Markdown
  3. Requires: xml.js
  4. Author: John Crepezzi <john.crepezzi@gmail.com>
  5. Website: https://daringfireball.net/projects/markdown/
  6. Category: common, markup
  7. */
  8. function markdown(hljs) {
  9. const INLINE_HTML = {
  10. begin: '<', end: '>',
  11. subLanguage: 'xml',
  12. relevance: 0
  13. };
  14. const HORIZONTAL_RULE = {
  15. begin: '^[-\\*]{3,}', end: '$'
  16. };
  17. const CODE = {
  18. className: 'code',
  19. variants: [
  20. // TODO: fix to allow these to work with sublanguage also
  21. { begin: '(`{3,})(.|\\n)*?\\1`*[ ]*', },
  22. { begin: '(~{3,})(.|\\n)*?\\1~*[ ]*', },
  23. // needed to allow markdown as a sublanguage to work
  24. { begin: '```', end: '```+[ ]*$' },
  25. { begin: '~~~', end: '~~~+[ ]*$' },
  26. { begin: '`.+?`' },
  27. {
  28. begin: '(?=^( {4}|\\t))',
  29. // use contains to gobble up multiple lines to allow the block to be whatever size
  30. // but only have a single open/close tag vs one per line
  31. contains: [
  32. { begin: '^( {4}|\\t)', end: '(\\n)$' }
  33. ],
  34. relevance: 0
  35. }
  36. ]
  37. };
  38. const LIST = {
  39. className: 'bullet',
  40. begin: '^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)',
  41. end: '\\s+',
  42. excludeEnd: true
  43. };
  44. const LINK_REFERENCE = {
  45. begin: /^\[[^\n]+\]:/,
  46. returnBegin: true,
  47. contains: [
  48. {
  49. className: 'symbol',
  50. begin: /\[/, end: /\]/,
  51. excludeBegin: true, excludeEnd: true
  52. },
  53. {
  54. className: 'link',
  55. begin: /:\s*/, end: /$/,
  56. excludeBegin: true
  57. }
  58. ]
  59. };
  60. const LINK = {
  61. begin: '\\[.+?\\][\\(\\[].*?[\\)\\]]',
  62. returnBegin: true,
  63. contains: [
  64. {
  65. className: 'string',
  66. begin: '\\[', end: '\\]',
  67. excludeBegin: true,
  68. returnEnd: true,
  69. relevance: 0
  70. },
  71. {
  72. className: 'link',
  73. begin: '\\]\\(', end: '\\)',
  74. excludeBegin: true, excludeEnd: true
  75. },
  76. {
  77. className: 'symbol',
  78. begin: '\\]\\[', end: '\\]',
  79. excludeBegin: true, excludeEnd: true
  80. }
  81. ],
  82. relevance: 10
  83. };
  84. const BOLD = {
  85. className: 'strong',
  86. contains: [],
  87. variants: [
  88. {begin: /_{2}/, end: /_{2}/ },
  89. {begin: /\*{2}/, end: /\*{2}/ }
  90. ]
  91. };
  92. const ITALIC = {
  93. className: 'emphasis',
  94. contains: [],
  95. variants: [
  96. { begin: /\*(?!\*)/, end: /\*/ },
  97. { begin: /_(?!_)/, end: /_/, relevance: 0},
  98. ]
  99. };
  100. BOLD.contains.push(ITALIC);
  101. ITALIC.contains.push(BOLD);
  102. var CONTAINABLE = [
  103. INLINE_HTML,
  104. LINK
  105. ];
  106. BOLD.contains = BOLD.contains.concat(CONTAINABLE);
  107. ITALIC.contains = ITALIC.contains.concat(CONTAINABLE);
  108. CONTAINABLE = CONTAINABLE.concat(BOLD,ITALIC);
  109. const HEADER = {
  110. className: 'section',
  111. variants: [
  112. {
  113. begin: '^#{1,6}',
  114. end: '$',
  115. contains: CONTAINABLE
  116. },
  117. {
  118. begin: '(?=^.+?\\n[=-]{2,}$)',
  119. contains: [
  120. { begin: '^[=-]*$' },
  121. { begin: '^', end: "\\n", contains: CONTAINABLE },
  122. ]
  123. }
  124. ]
  125. };
  126. const BLOCKQUOTE = {
  127. className: 'quote',
  128. begin: '^>\\s+',
  129. contains: CONTAINABLE,
  130. end: '$',
  131. };
  132. return {
  133. name: 'Markdown',
  134. aliases: ['md', 'mkdown', 'mkd'],
  135. contains: [
  136. HEADER,
  137. INLINE_HTML,
  138. LIST,
  139. BOLD,
  140. ITALIC,
  141. BLOCKQUOTE,
  142. CODE,
  143. HORIZONTAL_RULE,
  144. LINK,
  145. LINK_REFERENCE
  146. ]
  147. };
  148. }
  149. module.exports = markdown;