259 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			259 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/**
 | 
						|
 * @param {string} value
 | 
						|
 * @returns {RegExp}
 | 
						|
 * */
 | 
						|
 | 
						|
/**
 | 
						|
 * @param {RegExp | string } re
 | 
						|
 * @returns {string}
 | 
						|
 */
 | 
						|
function source(re) {
 | 
						|
  if (!re) return null;
 | 
						|
  if (typeof re === "string") return re;
 | 
						|
 | 
						|
  return re.source;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @param {...(RegExp | string) } args
 | 
						|
 * @returns {string}
 | 
						|
 */
 | 
						|
function concat(...args) {
 | 
						|
  const joined = args.map((x) => source(x)).join("");
 | 
						|
  return joined;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
Language: Markdown
 | 
						|
Requires: xml.js
 | 
						|
Author: John Crepezzi <john.crepezzi@gmail.com>
 | 
						|
Website: https://daringfireball.net/projects/markdown/
 | 
						|
Category: common, markup
 | 
						|
*/
 | 
						|
 | 
						|
function markdown(hljs) {
 | 
						|
  const INLINE_HTML = {
 | 
						|
    begin: /<\/?[A-Za-z_]/,
 | 
						|
    end: '>',
 | 
						|
    subLanguage: 'xml',
 | 
						|
    relevance: 0
 | 
						|
  };
 | 
						|
  const HORIZONTAL_RULE = {
 | 
						|
    begin: '^[-\\*]{3,}',
 | 
						|
    end: '$'
 | 
						|
  };
 | 
						|
  const CODE = {
 | 
						|
    className: 'code',
 | 
						|
    variants: [
 | 
						|
      // TODO: fix to allow these to work with sublanguage also
 | 
						|
      {
 | 
						|
        begin: '(`{3,})[^`](.|\\n)*?\\1`*[ ]*'
 | 
						|
      },
 | 
						|
      {
 | 
						|
        begin: '(~{3,})[^~](.|\\n)*?\\1~*[ ]*'
 | 
						|
      },
 | 
						|
      // needed to allow markdown as a sublanguage to work
 | 
						|
      {
 | 
						|
        begin: '```',
 | 
						|
        end: '```+[ ]*$'
 | 
						|
      },
 | 
						|
      {
 | 
						|
        begin: '~~~',
 | 
						|
        end: '~~~+[ ]*$'
 | 
						|
      },
 | 
						|
      {
 | 
						|
        begin: '`.+?`'
 | 
						|
      },
 | 
						|
      {
 | 
						|
        begin: '(?=^( {4}|\\t))',
 | 
						|
        // use contains to gobble up multiple lines to allow the block to be whatever size
 | 
						|
        // but only have a single open/close tag vs one per line
 | 
						|
        contains: [
 | 
						|
          {
 | 
						|
            begin: '^( {4}|\\t)',
 | 
						|
            end: '(\\n)$'
 | 
						|
          }
 | 
						|
        ],
 | 
						|
        relevance: 0
 | 
						|
      }
 | 
						|
    ]
 | 
						|
  };
 | 
						|
  const LIST = {
 | 
						|
    className: 'bullet',
 | 
						|
    begin: '^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)',
 | 
						|
    end: '\\s+',
 | 
						|
    excludeEnd: true
 | 
						|
  };
 | 
						|
  const LINK_REFERENCE = {
 | 
						|
    begin: /^\[[^\n]+\]:/,
 | 
						|
    returnBegin: true,
 | 
						|
    contains: [
 | 
						|
      {
 | 
						|
        className: 'symbol',
 | 
						|
        begin: /\[/,
 | 
						|
        end: /\]/,
 | 
						|
        excludeBegin: true,
 | 
						|
        excludeEnd: true
 | 
						|
      },
 | 
						|
      {
 | 
						|
        className: 'link',
 | 
						|
        begin: /:\s*/,
 | 
						|
        end: /$/,
 | 
						|
        excludeBegin: true
 | 
						|
      }
 | 
						|
    ]
 | 
						|
  };
 | 
						|
  const URL_SCHEME = /[A-Za-z][A-Za-z0-9+.-]*/;
 | 
						|
  const LINK = {
 | 
						|
    variants: [
 | 
						|
      // too much like nested array access in so many languages
 | 
						|
      // to have any real relevance
 | 
						|
      {
 | 
						|
        begin: /\[.+?\]\[.*?\]/,
 | 
						|
        relevance: 0
 | 
						|
      },
 | 
						|
      // popular internet URLs
 | 
						|
      {
 | 
						|
        begin: /\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/,
 | 
						|
        relevance: 2
 | 
						|
      },
 | 
						|
      {
 | 
						|
        begin: concat(/\[.+?\]\(/, URL_SCHEME, /:\/\/.*?\)/),
 | 
						|
        relevance: 2
 | 
						|
      },
 | 
						|
      // relative urls
 | 
						|
      {
 | 
						|
        begin: /\[.+?\]\([./?&#].*?\)/,
 | 
						|
        relevance: 1
 | 
						|
      },
 | 
						|
      // whatever else, lower relevance (might not be a link at all)
 | 
						|
      {
 | 
						|
        begin: /\[.+?\]\(.*?\)/,
 | 
						|
        relevance: 0
 | 
						|
      }
 | 
						|
    ],
 | 
						|
    returnBegin: true,
 | 
						|
    contains: [
 | 
						|
      {
 | 
						|
        className: 'string',
 | 
						|
        relevance: 0,
 | 
						|
        begin: '\\[',
 | 
						|
        end: '\\]',
 | 
						|
        excludeBegin: true,
 | 
						|
        returnEnd: true
 | 
						|
      },
 | 
						|
      {
 | 
						|
        className: 'link',
 | 
						|
        relevance: 0,
 | 
						|
        begin: '\\]\\(',
 | 
						|
        end: '\\)',
 | 
						|
        excludeBegin: true,
 | 
						|
        excludeEnd: true
 | 
						|
      },
 | 
						|
      {
 | 
						|
        className: 'symbol',
 | 
						|
        relevance: 0,
 | 
						|
        begin: '\\]\\[',
 | 
						|
        end: '\\]',
 | 
						|
        excludeBegin: true,
 | 
						|
        excludeEnd: true
 | 
						|
      }
 | 
						|
    ]
 | 
						|
  };
 | 
						|
  const BOLD = {
 | 
						|
    className: 'strong',
 | 
						|
    contains: [], // defined later
 | 
						|
    variants: [
 | 
						|
      {
 | 
						|
        begin: /_{2}/,
 | 
						|
        end: /_{2}/
 | 
						|
      },
 | 
						|
      {
 | 
						|
        begin: /\*{2}/,
 | 
						|
        end: /\*{2}/
 | 
						|
      }
 | 
						|
    ]
 | 
						|
  };
 | 
						|
  const ITALIC = {
 | 
						|
    className: 'emphasis',
 | 
						|
    contains: [], // defined later
 | 
						|
    variants: [
 | 
						|
      {
 | 
						|
        begin: /\*(?!\*)/,
 | 
						|
        end: /\*/
 | 
						|
      },
 | 
						|
      {
 | 
						|
        begin: /_(?!_)/,
 | 
						|
        end: /_/,
 | 
						|
        relevance: 0
 | 
						|
      }
 | 
						|
    ]
 | 
						|
  };
 | 
						|
  BOLD.contains.push(ITALIC);
 | 
						|
  ITALIC.contains.push(BOLD);
 | 
						|
 | 
						|
  let CONTAINABLE = [
 | 
						|
    INLINE_HTML,
 | 
						|
    LINK
 | 
						|
  ];
 | 
						|
 | 
						|
  BOLD.contains = BOLD.contains.concat(CONTAINABLE);
 | 
						|
  ITALIC.contains = ITALIC.contains.concat(CONTAINABLE);
 | 
						|
 | 
						|
  CONTAINABLE = CONTAINABLE.concat(BOLD, ITALIC);
 | 
						|
 | 
						|
  const HEADER = {
 | 
						|
    className: 'section',
 | 
						|
    variants: [
 | 
						|
      {
 | 
						|
        begin: '^#{1,6}',
 | 
						|
        end: '$',
 | 
						|
        contains: CONTAINABLE
 | 
						|
      },
 | 
						|
      {
 | 
						|
        begin: '(?=^.+?\\n[=-]{2,}$)',
 | 
						|
        contains: [
 | 
						|
          {
 | 
						|
            begin: '^[=-]*$'
 | 
						|
          },
 | 
						|
          {
 | 
						|
            begin: '^',
 | 
						|
            end: "\\n",
 | 
						|
            contains: CONTAINABLE
 | 
						|
          }
 | 
						|
        ]
 | 
						|
      }
 | 
						|
    ]
 | 
						|
  };
 | 
						|
 | 
						|
  const BLOCKQUOTE = {
 | 
						|
    className: 'quote',
 | 
						|
    begin: '^>\\s+',
 | 
						|
    contains: CONTAINABLE,
 | 
						|
    end: '$'
 | 
						|
  };
 | 
						|
 | 
						|
  return {
 | 
						|
    name: 'Markdown',
 | 
						|
    aliases: [
 | 
						|
      'md',
 | 
						|
      'mkdown',
 | 
						|
      'mkd'
 | 
						|
    ],
 | 
						|
    contains: [
 | 
						|
      HEADER,
 | 
						|
      INLINE_HTML,
 | 
						|
      LIST,
 | 
						|
      BOLD,
 | 
						|
      ITALIC,
 | 
						|
      BLOCKQUOTE,
 | 
						|
      CODE,
 | 
						|
      HORIZONTAL_RULE,
 | 
						|
      LINK,
 | 
						|
      LINK_REFERENCE
 | 
						|
    ]
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
module.exports = markdown;
 |