From 21b72f78546fe8fde457be780c57c5bed6fdb40a Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 9 Feb 2017 19:41:17 +0900 Subject: [PATCH] #139 --- src/common/text/elements/code.js | 186 +++++++++++++++++++- src/web/app/base.styl | 23 +++ src/web/app/common/scripts/text-compiler.js | 2 +- 3 files changed, 209 insertions(+), 2 deletions(-) diff --git a/src/common/text/elements/code.js b/src/common/text/elements/code.js index d046716ed..190a090d9 100644 --- a/src/common/text/elements/code.js +++ b/src/common/text/elements/code.js @@ -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(/ 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: `${escape(comment)}`, + 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: `${escape(str)}`, + 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: `${match}`, + 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: `${match}`, + next: match.length + }; + } else { + return null; + } + }, + + // symbol + code => { + const match = symbols.filter(s => code[0] == s)[0]; + if (match) { + return { + html: `${match}`, + 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; +} diff --git a/src/web/app/base.styl b/src/web/app/base.styl index 5eab20548..4082fa24c 100644 --- a/src/web/app/base.styl +++ b/src/web/app/base.styl @@ -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 diff --git a/src/web/app/common/scripts/text-compiler.js b/src/web/app/common/scripts/text-compiler.js index ab322764f..29b700e62 100644 --- a/src/web/app/common/scripts/text-compiler.js +++ b/src/web/app/common/scripts/text-compiler.js @@ -31,7 +31,7 @@ module.exports = function(tokens, shouldBreak, shouldEscape) { case 'hashtag': // TODO return '' + escape(token.content) + ''; case 'code': - return '
' + escape(token.code) + '
'; + return '
' + token.codeHtml + '
'; } }).join('');