问题1:Python中没有指针导致循环出错
解决方法:
由于循环的是在一个turple中循环,即使本轮循环中循环变量i的值改变了,但是本轮循环结束在下次循环开始时,循环变量i仍然会被重新赋值为turple中的下一个元素,导致用i作为指针来寻得数组对应下标元素的方法失败。
因此,增添一个变量充当指针,控制循环变量i的值,若搜索位置大于turple中下一个元素的值,continue,直到i追上pointer。这样,自定义的一个指针就可以使用了。
# 词法分析
def analyze(self):
self.furnace = ''
# 蟒生污点 不能修改循环遍历 自建指针
pointer = -1 # pointer初始化为0时 第一个字符无法读取 所以初始化为-1
for i in range(len(self.raw)):
# 判断循环变量与指针的位置
if i <= pointer:
continue
else:
if self.is_letter(self.raw[i]) or self.is_underline(self.raw[i]) or self.is_sharp(self.raw[i]):
# 读入该字符 移动指针
self.furnace += self.raw[i]
i += 1
pointer = i
# 使用 while 读完整个单词和下一位 然后回退一位
# #include 等只能以#打头 中间不允许出现 所以这里不包含 self.is_sharp(self.raw[i])
while self.is_letter(self.raw[i]) or self.is_underline(self.raw[i]) or self.is_digit(self.raw[i]):
self.furnace += self.raw[i]
# 修改临时循环变量通过 while 读取下一个字符
i += 1
# 修改自定义指针
pointer = i
# 【重点】多读一位 -> 回退
pointer -= 1
elif:
.......
问题2:双引号、单引号内的字符串转义字符无法高亮展示
解决方法:
version1.0版本中生成HTML文件展示时可以高亮显示:
<span class="string">'123<strong class="escape">\t</strong><strong class="escape">\n</strong>'</span>
但是在version2.0版本中实时渲染HTML时会被当做字符串不被渲染,因此只能退而求其次在识别转义字符时直接存储为HTML文本并赋予css样式
# 转义字符
if self.is_slash(self.raw[i]):
self.furnace += "<strong class=\"escape\">" + self.raw[i] + self.raw[i + 1] + "</strong>"
i += 2
pointer = i
问题3:输出在HTML页面时,空格和换行键需要二次转义
解决方法:
渲染特殊字符如:空格、制表符、换行时由于HTML作为标记语言对这些特殊符号需要二次转义。
# 转义
def trans(self, ch):
if self.is_enter(ch):
return "<br>"
elif self.is_tab(ch):
return " "
elif ch == ' ':
return " "
else:
return ch
<span>\t</span>无法显示制表符
需要改为<span> </span>
<span> </span>无法显示多个空格,大于等于两个空格仅会被识别为一个
需要改为<span>    </span>
<span>\n</span>无法显示换行
需要改为<span><br></span>
问题4:渲染出的高亮内容引用CSS样式失效
解决方法:
虽然可以绑定:class 但是没有 deep 所以不会渲染 使用 >>> 修改 css 选择器
举两个栗子:
.grid-content >>> .sharpe-special {
color: orange;
}
.grid-content >>> .arrow-special {
color: turquoise;
}
问题5:textarea输入Tab键不被读入反而会切换focus组件
解决方法:
由于tab键被浏览器绑定为切换focus组件,因此在输入框内输入tab键时无法被读入。因此,在页面渲染完成之后立即对tab键进行全局监听,当tab按下时首先阻止默认绑定的事件发生,然后在输入框光标所在位置插入转义字符\t。
document.onkeydown = function (e) {
let key = window.event.keyCode; // tab的值为9
// console.log(event.shiftKey);
// console.log(key);
if (key === 9) {
// 阻止默认事件
window.event.preventDefault();
// 获取输入框信息
let elInput = document.getElementById("userInput");
let startPos = elInput.selectionStart;
let endPos = elInput.selectionEnd;
if (startPos === undefined || endPos === undefined) return;
let txt = elInput.value;
// 插入文本
elInput.value = txt.substring(0, startPos) + "\t" + txt.substring(endPos); // 中间为插入文本
elInput.focus();
elInput.selectionStart = startPos + 1; // 插入字符的长度
elInput.selectionEnd = startPos + 1; // 插入字符的长度
}
}
问题6:@on-change监听textarea内容失效
解决方法:
由于Vuejs是原生框架但是ElementUI是经过二次开发的组件并且现在仍在不停更新和修复Bug,一些事件的绑定可能会导致冲突而无法使用。因此打算改用全局watch监听器。watch可以监控一个值的变换,并调用因为变化需要执行的方法——可以实现实时的代码高亮,可以通过watch动态改变关联的状态——对输入内容进行实时双向绑定改变。
使用watch监听变量code即左边textarea中用户输入的文本内容,如果发生改变则访问接口将用户输入代码传给后端并从接受后端返回的高亮HTML代码赋值与变量beauty。
watch: {
code: function (val, old) {
调用接口;
}
问题7:自定义输入框的样式不被渲染
解决方法:
直接在style标签中使用css选择器对组件el-textarea进行样式的添加只会改变其外部样式,原因是因为组件el-textarea是原生组件的封装,内部仍有若干原生组件,因此需要改变的内部组件的样式。使用F12对元素进行检查发现其内部输入框的样式选择器名称为el-textarea__inner,因此对其进行二次加工即可。