l0bsterssg

node.js static responsive blog post generator
Log | Files | Refs | README

markdown.js (3424B)


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