This commit is contained in:
		
							parent
							
								
									e04c03007b
								
							
						
					
					
						commit
						21b72f7854
					
				
					 3 changed files with 209 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -11,7 +11,191 @@ module.exports = {
 | 
			
		|||
		return {
 | 
			
		||||
			type: 'code',
 | 
			
		||||
			content: code,
 | 
			
		||||
			code: code.substr(3, code.length - 6).trim()
 | 
			
		||||
			code: code.substr(3, code.length - 6).trim(),
 | 
			
		||||
			codeHtml: genHtml(code.substr(3, code.length - 6).trim())
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function escape(text) {
 | 
			
		||||
	return text
 | 
			
		||||
		.replace(/>/g, '>')
 | 
			
		||||
		.replace(/</g, '<');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 文字数が多い順にソートします
 | 
			
		||||
// そうしないと、「function」という文字列が与えられたときに「func」が先にマッチしてしまう可能性があるためです
 | 
			
		||||
const keywords = [
 | 
			
		||||
	'true',
 | 
			
		||||
	'false',
 | 
			
		||||
	'null',
 | 
			
		||||
	'nil',
 | 
			
		||||
	'undefined',
 | 
			
		||||
	'var',
 | 
			
		||||
	'const',
 | 
			
		||||
	'let',
 | 
			
		||||
	'mut',
 | 
			
		||||
	'if',
 | 
			
		||||
	'then',
 | 
			
		||||
	'else',
 | 
			
		||||
	'switch',
 | 
			
		||||
	'case',
 | 
			
		||||
	'for',
 | 
			
		||||
	'each',
 | 
			
		||||
	'in',
 | 
			
		||||
	'while',
 | 
			
		||||
	'loop',
 | 
			
		||||
	'continue',
 | 
			
		||||
	'break',
 | 
			
		||||
	'do',
 | 
			
		||||
	'goto',
 | 
			
		||||
	'end',
 | 
			
		||||
	'function',
 | 
			
		||||
	'func',
 | 
			
		||||
	'fn',
 | 
			
		||||
	'return',
 | 
			
		||||
	'async',
 | 
			
		||||
	'await',
 | 
			
		||||
	'require',
 | 
			
		||||
	'import',
 | 
			
		||||
	'export',
 | 
			
		||||
	'new',
 | 
			
		||||
	'this',
 | 
			
		||||
	'class',
 | 
			
		||||
	'constructor'
 | 
			
		||||
].sort((a, b) => b.length - a.length);
 | 
			
		||||
 | 
			
		||||
const symbols = [
 | 
			
		||||
	'=',
 | 
			
		||||
	'+',
 | 
			
		||||
	'-',
 | 
			
		||||
	'*',
 | 
			
		||||
	'/',
 | 
			
		||||
	'%',
 | 
			
		||||
	'^',
 | 
			
		||||
	'&',
 | 
			
		||||
	'|',
 | 
			
		||||
	'>',
 | 
			
		||||
	'<',
 | 
			
		||||
	'~'
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
const elements = [
 | 
			
		||||
	// comment
 | 
			
		||||
	code => {
 | 
			
		||||
		if (code.substr(0, 2) != '//') return null;
 | 
			
		||||
		const comment = code.match(/^\/\/(.+?)\n/)[0];
 | 
			
		||||
		return {
 | 
			
		||||
			html: `<span class="comment">${escape(comment)}</span>`,
 | 
			
		||||
			next: comment.length
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	// string
 | 
			
		||||
	code => {
 | 
			
		||||
		if (!/^['"`]/.test(code)) return null;
 | 
			
		||||
		const begin = code[0];
 | 
			
		||||
		let str = begin;
 | 
			
		||||
		let thisIsNotAString = false;
 | 
			
		||||
		for (i = 1; i < code.length; i++) {
 | 
			
		||||
			const char = code[i];
 | 
			
		||||
			if (char == '\\') {
 | 
			
		||||
				i++;
 | 
			
		||||
				continue;
 | 
			
		||||
			} else if (char == begin) {
 | 
			
		||||
				str += char;
 | 
			
		||||
				break;
 | 
			
		||||
			} else if (char == '\n' || i == (code.length - 1)) {
 | 
			
		||||
				thisIsNotAString = true;
 | 
			
		||||
				break;
 | 
			
		||||
			} else {
 | 
			
		||||
				str += char;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (thisIsNotAString) {
 | 
			
		||||
			return null;
 | 
			
		||||
		} else {
 | 
			
		||||
			return {
 | 
			
		||||
				html: `<span class="string">${escape(str)}</span>`,
 | 
			
		||||
				next: str.length
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	// number
 | 
			
		||||
	(code, i, source) => {
 | 
			
		||||
		const prev = source[i - 1];
 | 
			
		||||
		if (prev && /[a-zA-Z]/.test(prev)) return null;
 | 
			
		||||
		if (!/^[0-9]+/.test(code)) return null;
 | 
			
		||||
		const match = code.match(/^[0-9]+/)[0];
 | 
			
		||||
		if (match) {
 | 
			
		||||
			return {
 | 
			
		||||
				html: `<span class="number">${match}</span>`,
 | 
			
		||||
				next: match.length
 | 
			
		||||
			};
 | 
			
		||||
		} else {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	// keyword
 | 
			
		||||
	code => {
 | 
			
		||||
		const match = keywords.filter(k => code.substr(0, k.length) == k)[0];
 | 
			
		||||
		if (match) {
 | 
			
		||||
			if (/^[a-zA-Z]/.test(code.substr(match.length))) return null;
 | 
			
		||||
			return {
 | 
			
		||||
				html: `<span class="keyword ${match}">${match}</span>`,
 | 
			
		||||
				next: match.length
 | 
			
		||||
			};
 | 
			
		||||
		} else {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	// symbol
 | 
			
		||||
	code => {
 | 
			
		||||
		const match = symbols.filter(s => code[0] == s)[0];
 | 
			
		||||
		if (match) {
 | 
			
		||||
			return {
 | 
			
		||||
				html: `<span class="symbol">${match}</span>`,
 | 
			
		||||
				next: 1
 | 
			
		||||
			};
 | 
			
		||||
		} else {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
// specify lang is todo
 | 
			
		||||
function genHtml(source, lang) {
 | 
			
		||||
	let code = source;
 | 
			
		||||
	let html = '';
 | 
			
		||||
 | 
			
		||||
	function push(token) {
 | 
			
		||||
		html += token.html;
 | 
			
		||||
		code = code.substr(token.next);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	let i = 0;
 | 
			
		||||
 | 
			
		||||
	while (code != '') {
 | 
			
		||||
		const parsed = elements.some(el => {
 | 
			
		||||
			const e = el(code, i, source);
 | 
			
		||||
			if (e) {
 | 
			
		||||
				push(e);
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		if (!parsed) {
 | 
			
		||||
			push({
 | 
			
		||||
				html: escape(code[0]),
 | 
			
		||||
				next: 1
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return html;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,6 +107,29 @@ a
 | 
			
		|||
	*
 | 
			
		||||
		cursor pointer
 | 
			
		||||
 | 
			
		||||
pre > code
 | 
			
		||||
	.comment
 | 
			
		||||
		opacity 0.5
 | 
			
		||||
 | 
			
		||||
	.string
 | 
			
		||||
		color #e96900
 | 
			
		||||
 | 
			
		||||
	.keyword
 | 
			
		||||
		color #2973b7
 | 
			
		||||
 | 
			
		||||
		&.true
 | 
			
		||||
		&.false
 | 
			
		||||
		&.null
 | 
			
		||||
		&.nil
 | 
			
		||||
		&.undefined
 | 
			
		||||
			color #ae81ff
 | 
			
		||||
 | 
			
		||||
	.symbol
 | 
			
		||||
		color #42b983
 | 
			
		||||
 | 
			
		||||
	.number
 | 
			
		||||
		color #ae81ff
 | 
			
		||||
 | 
			
		||||
mk-locker
 | 
			
		||||
	display block
 | 
			
		||||
	position fixed
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ module.exports = function(tokens, shouldBreak, shouldEscape) {
 | 
			
		|||
			case 'hashtag': // TODO
 | 
			
		||||
				return '<a>' + escape(token.content) + '</a>';
 | 
			
		||||
			case 'code':
 | 
			
		||||
				return '<pre><code>' + escape(token.code) + '</code></pre>';
 | 
			
		||||
				return '<pre><code>' + token.codeHtml + '</code></pre>';
 | 
			
		||||
		}
 | 
			
		||||
	}).join('');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue