304 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			304 lines
		
	
	
		
			6.7 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: AsciiDoc
 | 
						|
Requires: xml.js
 | 
						|
Author: Dan Allen <dan.j.allen@gmail.com>
 | 
						|
Website: http://asciidoc.org
 | 
						|
Description: A semantic, text-based document format that can be exported to HTML, DocBook and other backends.
 | 
						|
Category: markup
 | 
						|
*/
 | 
						|
 | 
						|
/** @type LanguageFn */
 | 
						|
function asciidoc(hljs) {
 | 
						|
  const HORIZONTAL_RULE = {
 | 
						|
    begin: '^\'{3,}[ \\t]*$',
 | 
						|
    relevance: 10
 | 
						|
  };
 | 
						|
  const ESCAPED_FORMATTING = [
 | 
						|
    // escaped constrained formatting marks (i.e., \* \_ or \`)
 | 
						|
    {
 | 
						|
      begin: /\\[*_`]/
 | 
						|
    },
 | 
						|
    // escaped unconstrained formatting marks (i.e., \\** \\__ or \\``)
 | 
						|
    // must ignore until the next formatting marks
 | 
						|
    // this rule might not be 100% compliant with Asciidoctor 2.0 but we are entering undefined behavior territory...
 | 
						|
    {
 | 
						|
      begin: /\\\\\*{2}[^\n]*?\*{2}/
 | 
						|
    },
 | 
						|
    {
 | 
						|
      begin: /\\\\_{2}[^\n]*_{2}/
 | 
						|
    },
 | 
						|
    {
 | 
						|
      begin: /\\\\`{2}[^\n]*`{2}/
 | 
						|
    },
 | 
						|
    // guard: constrained formatting mark may not be preceded by ":", ";" or
 | 
						|
    // "}". match these so the constrained rule doesn't see them
 | 
						|
    {
 | 
						|
      begin: /[:;}][*_`](?![*_`])/
 | 
						|
    }
 | 
						|
  ];
 | 
						|
  const STRONG = [
 | 
						|
    // inline unconstrained strong (single line)
 | 
						|
    {
 | 
						|
      className: 'strong',
 | 
						|
      begin: /\*{2}([^\n]+?)\*{2}/
 | 
						|
    },
 | 
						|
    // inline unconstrained strong (multi-line)
 | 
						|
    {
 | 
						|
      className: 'strong',
 | 
						|
      begin: concat(
 | 
						|
        /\*\*/,
 | 
						|
        /((\*(?!\*)|\\[^\n]|[^*\n\\])+\n)+/,
 | 
						|
        /(\*(?!\*)|\\[^\n]|[^*\n\\])*/,
 | 
						|
        /\*\*/
 | 
						|
      ),
 | 
						|
      relevance: 0
 | 
						|
    },
 | 
						|
    // inline constrained strong (single line)
 | 
						|
    {
 | 
						|
      className: 'strong',
 | 
						|
      // must not precede or follow a word character
 | 
						|
      begin: /\B\*(\S|\S[^\n]*?\S)\*(?!\w)/
 | 
						|
    },
 | 
						|
    // inline constrained strong (multi-line)
 | 
						|
    {
 | 
						|
      className: 'strong',
 | 
						|
      // must not precede or follow a word character
 | 
						|
      begin: /\*[^\s]([^\n]+\n)+([^\n]+)\*/
 | 
						|
    }
 | 
						|
  ];
 | 
						|
  const EMPHASIS = [
 | 
						|
    // inline unconstrained emphasis (single line)
 | 
						|
    {
 | 
						|
      className: 'emphasis',
 | 
						|
      begin: /_{2}([^\n]+?)_{2}/
 | 
						|
    },
 | 
						|
    // inline unconstrained emphasis (multi-line)
 | 
						|
    {
 | 
						|
      className: 'emphasis',
 | 
						|
      begin: concat(
 | 
						|
        /__/,
 | 
						|
        /((_(?!_)|\\[^\n]|[^_\n\\])+\n)+/,
 | 
						|
        /(_(?!_)|\\[^\n]|[^_\n\\])*/,
 | 
						|
        /__/
 | 
						|
      ),
 | 
						|
      relevance: 0
 | 
						|
    },
 | 
						|
    // inline constrained emphasis (single line)
 | 
						|
    {
 | 
						|
      className: 'emphasis',
 | 
						|
      // must not precede or follow a word character
 | 
						|
      begin: /\b_(\S|\S[^\n]*?\S)_(?!\w)/
 | 
						|
    },
 | 
						|
    // inline constrained emphasis (multi-line)
 | 
						|
    {
 | 
						|
      className: 'emphasis',
 | 
						|
      // must not precede or follow a word character
 | 
						|
      begin: /_[^\s]([^\n]+\n)+([^\n]+)_/
 | 
						|
    },
 | 
						|
    // inline constrained emphasis using single quote (legacy)
 | 
						|
    {
 | 
						|
      className: 'emphasis',
 | 
						|
      // must not follow a word character or be followed by a single quote or space
 | 
						|
      begin: '\\B\'(?![\'\\s])',
 | 
						|
      end: '(\\n{2}|\')',
 | 
						|
      // allow escaped single quote followed by word char
 | 
						|
      contains: [{
 | 
						|
        begin: '\\\\\'\\w',
 | 
						|
        relevance: 0
 | 
						|
      }],
 | 
						|
      relevance: 0
 | 
						|
    }
 | 
						|
  ];
 | 
						|
  const ADMONITION = {
 | 
						|
    className: 'symbol',
 | 
						|
    begin: '^(NOTE|TIP|IMPORTANT|WARNING|CAUTION):\\s+',
 | 
						|
    relevance: 10
 | 
						|
  };
 | 
						|
  const BULLET_LIST = {
 | 
						|
    className: 'bullet',
 | 
						|
    begin: '^(\\*+|-+|\\.+|[^\\n]+?::)\\s+'
 | 
						|
  };
 | 
						|
 | 
						|
  return {
 | 
						|
    name: 'AsciiDoc',
 | 
						|
    aliases: ['adoc'],
 | 
						|
    contains: [
 | 
						|
      // block comment
 | 
						|
      hljs.COMMENT(
 | 
						|
        '^/{4,}\\n',
 | 
						|
        '\\n/{4,}$',
 | 
						|
        // can also be done as...
 | 
						|
        // '^/{4,}$',
 | 
						|
        // '^/{4,}$',
 | 
						|
        {
 | 
						|
          relevance: 10
 | 
						|
        }
 | 
						|
      ),
 | 
						|
      // line comment
 | 
						|
      hljs.COMMENT(
 | 
						|
        '^//',
 | 
						|
        '$',
 | 
						|
        {
 | 
						|
          relevance: 0
 | 
						|
        }
 | 
						|
      ),
 | 
						|
      // title
 | 
						|
      {
 | 
						|
        className: 'title',
 | 
						|
        begin: '^\\.\\w.*$'
 | 
						|
      },
 | 
						|
      // example, admonition & sidebar blocks
 | 
						|
      {
 | 
						|
        begin: '^[=\\*]{4,}\\n',
 | 
						|
        end: '\\n^[=\\*]{4,}$',
 | 
						|
        relevance: 10
 | 
						|
      },
 | 
						|
      // headings
 | 
						|
      {
 | 
						|
        className: 'section',
 | 
						|
        relevance: 10,
 | 
						|
        variants: [
 | 
						|
          {
 | 
						|
            begin: '^(={1,6})[ \t].+?([ \t]\\1)?$'
 | 
						|
          },
 | 
						|
          {
 | 
						|
            begin: '^[^\\[\\]\\n]+?\\n[=\\-~\\^\\+]{2,}$'
 | 
						|
          }
 | 
						|
        ]
 | 
						|
      },
 | 
						|
      // document attributes
 | 
						|
      {
 | 
						|
        className: 'meta',
 | 
						|
        begin: '^:.+?:',
 | 
						|
        end: '\\s',
 | 
						|
        excludeEnd: true,
 | 
						|
        relevance: 10
 | 
						|
      },
 | 
						|
      // block attributes
 | 
						|
      {
 | 
						|
        className: 'meta',
 | 
						|
        begin: '^\\[.+?\\]$',
 | 
						|
        relevance: 0
 | 
						|
      },
 | 
						|
      // quoteblocks
 | 
						|
      {
 | 
						|
        className: 'quote',
 | 
						|
        begin: '^_{4,}\\n',
 | 
						|
        end: '\\n_{4,}$',
 | 
						|
        relevance: 10
 | 
						|
      },
 | 
						|
      // listing and literal blocks
 | 
						|
      {
 | 
						|
        className: 'code',
 | 
						|
        begin: '^[\\-\\.]{4,}\\n',
 | 
						|
        end: '\\n[\\-\\.]{4,}$',
 | 
						|
        relevance: 10
 | 
						|
      },
 | 
						|
      // passthrough blocks
 | 
						|
      {
 | 
						|
        begin: '^\\+{4,}\\n',
 | 
						|
        end: '\\n\\+{4,}$',
 | 
						|
        contains: [{
 | 
						|
          begin: '<',
 | 
						|
          end: '>',
 | 
						|
          subLanguage: 'xml',
 | 
						|
          relevance: 0
 | 
						|
        }],
 | 
						|
        relevance: 10
 | 
						|
      },
 | 
						|
 | 
						|
      BULLET_LIST,
 | 
						|
      ADMONITION,
 | 
						|
      ...ESCAPED_FORMATTING,
 | 
						|
      ...STRONG,
 | 
						|
      ...EMPHASIS,
 | 
						|
 | 
						|
      // inline smart quotes
 | 
						|
      {
 | 
						|
        className: 'string',
 | 
						|
        variants: [
 | 
						|
          {
 | 
						|
            begin: "``.+?''"
 | 
						|
          },
 | 
						|
          {
 | 
						|
            begin: "`.+?'"
 | 
						|
          }
 | 
						|
        ]
 | 
						|
      },
 | 
						|
      // inline unconstrained emphasis
 | 
						|
      {
 | 
						|
        className: 'code',
 | 
						|
        begin: /`{2}/,
 | 
						|
        end: /(\n{2}|`{2})/
 | 
						|
      },
 | 
						|
      // inline code snippets (TODO should get same treatment as strong and emphasis)
 | 
						|
      {
 | 
						|
        className: 'code',
 | 
						|
        begin: '(`.+?`|\\+.+?\\+)',
 | 
						|
        relevance: 0
 | 
						|
      },
 | 
						|
      // indented literal block
 | 
						|
      {
 | 
						|
        className: 'code',
 | 
						|
        begin: '^[ \\t]',
 | 
						|
        end: '$',
 | 
						|
        relevance: 0
 | 
						|
      },
 | 
						|
      HORIZONTAL_RULE,
 | 
						|
      // images and links
 | 
						|
      {
 | 
						|
        begin: '(link:)?(http|https|ftp|file|irc|image:?):\\S+?\\[[^[]*?\\]',
 | 
						|
        returnBegin: true,
 | 
						|
        contains: [
 | 
						|
          {
 | 
						|
            begin: '(link|image:?):',
 | 
						|
            relevance: 0
 | 
						|
          },
 | 
						|
          {
 | 
						|
            className: 'link',
 | 
						|
            begin: '\\w',
 | 
						|
            end: '[^\\[]+',
 | 
						|
            relevance: 0
 | 
						|
          },
 | 
						|
          {
 | 
						|
            className: 'string',
 | 
						|
            begin: '\\[',
 | 
						|
            end: '\\]',
 | 
						|
            excludeBegin: true,
 | 
						|
            excludeEnd: true,
 | 
						|
            relevance: 0
 | 
						|
          }
 | 
						|
        ],
 | 
						|
        relevance: 10
 | 
						|
      }
 | 
						|
    ]
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
module.exports = asciidoc;
 |