javascript - 基于 javascript 的自定义代码编辑器的缩进
问题描述
我正在为自己创建的语言制作自定义代码编辑器。到目前为止,我已经使用 javascriprt span 类实现了语法高亮。现在我想在 IF ELSE 嵌套循环前面添加适当的间距或制表符空间。我不太擅长 javascript。
以下是我到目前为止编写的代码。
<!DOCTYPE html>
<html>
<body>
<style>
.code-str { color: #008000; }
.code-elem{ color: #ff0000;}
.code-comment { color: #0000FF; }
</style>
<textarea rows="20" cols="100" type="text" id="text2">Code to test
###IFLISTING:7786###
replaces
###ENDIFLISTING:7786###
Paste this code in the text area below and see the magic </textarea>
<textarea rows="20" cols="100" type="text" id="text1"></textarea>
<button onclick="myFunction()">MAGIC</button>
<script>
function myFunction() {
var str = document.getElementById("text1").value;
str = str.replace(/###IF(.*?)###/g, '<span class="code-elem"></br> </br>###IF$1### </br></span>');
str = str.replace(/###ENDIF(.*?)###/g, '<span class="code-elem"></br> ###ENDIF$1### </br></span>');
str = str.replace(/###IFLISTING(.*?)###/g, '<span class="code-str"> ###IFLISTING$1### </span>');
str = str.replace(/###ENDIFLISTING(.*?)###/g, '<span class="code-str">###ENDIFLISTING$1### </span>');
str = str.replace(/###VAR(.*?)###/g, '<span class="code-comment"> ###VAR$1### </span>');
str = str.replace(/###LISTING(.*?)###/g, '<span class="code-comment"> ###LISTING$1### </span>');
document.getElementById("demo").innerHTML = str;
}
</script>
<p id="demo"></p>
</body>
</html>
现在我想要的是嵌套的 IF ELSE 循环应该通过适当的缩进清楚地看到。我心中有一些粗略的看法。我想我应该使用 FOR 循环,然后使用计数器来增加 IF 和 ELSE 计数。但我不知道该怎么做。谁能给我一个想法?
我会非常感谢最小的帮助或建议。
解决方案
您将不得不迭代所有行,不仅是那些具有匹配关键字的行,然后保持当前缩进,您为某些关键字增加该缩进,而为其他一些关键字减少该缩进。我会将这种缩进影响存储为每个关键字的属性,在它们的样式属性旁边:
const keywords = {
IF: { style: "code-elem", indent: 4 },
ENDIF: { style: "code-elem", indent: -4 },
IFLISTING: { style: "code-str", indent: 4 },
ENDIFLISTING: { style: "code-str", indent: -4 },
VAR: { style: "code-comment", indent: 0 },
LISTING: { style: "code-comment", indent: 0 }
};
function myFunction() {
let indent = 0;
document.getElementById("demo").innerHTML = document.getElementById("text1").value.split(/[\r\n]+/).map(line => {
const oldIndent = indent;
line = line.trim().replace(/###([A-Z]+)(.*?)###/g, (m, keyword, arg) => {
const param = keywords[keyword];
if (!param) return m;
indent += param.indent;
return `<span class="${param.style}">${m}</span>`;
});
return " ".repeat(Math.min(indent, oldIndent)) + line;
}).join("<br>");
}
.code-str { color: #080; }
.code-elem { color: #f00;}
.code-comment { color: #00f; }
<textarea rows="15" cols="80" type="text" id="text1">###VAR:837:Single###
###IF:69154!=1###
###IF:69154!=1###
###VAR:69154:Single###x
###ENDIF:69154###
###VAR:69154:Single###x
###ENDIF:69154###
###VAR:990:Single### battery ###VAR:S301:Single###mAh (###VAR:S302:Single###V)
###IFLISTING:7785###
replaces
###ENDIFLISTING:7785###
###IFLISTING:7786###
replaces
###ENDIFLISTING:7786###
</textarea><br>
<button onclick="myFunction()">MAGIC</button>
<p id="demo"></p>
推荐阅读
- r - 在练习中创建箱线图
- xamarin - 如何在 Xamarin Forms 中以适当的图像比例在 UWP 中设置 SpashScreen?
- javascript - 编写一个满足以下测试的函数 f
- ios - NSInvalidArgumentException:Workout_Tracker.QuickAddViewController collectionView:numberOfItemsInSection:]:无法识别的选择器发送到实例
- vba - Excel - 在单独的工作表中输入 A 列的值时,粘贴 2 列引用的 B 列的值
- react-native - Expo React Native - 构建 apk 后组件切换位置/使用 QR 码打开
- vue.js - nuxt 应用程序中的 Vuex 抛出“不要在突变处理程序之外改变 vuex 存储状态”!
- c# - 在 C# 中调用 AWS Lambda 函数
- elasticsearch - 为 json 中的数据选择正确的日期格式
- javascript - CSS 过渡不能在与样式更改相反的方向上工作?