文本自动对齐功能探索实现
发布日期:2021-06-30 10:11:39
浏览次数:3
分类:技术文章
本文共 4680 字,大约阅读时间需要 15 分钟。
自动对齐的支持: 思路: 目前想到的是简单地保存前缀空格和,根据语句与当前空格和预测下一行空格和。
if elif else endif 支持
例如遇到If下一行预测就是前缀加一个tab大小的空格,而elif ,else ,endif则无法使用预测的前缀空格,因为他们要特殊地和对应的if对齐,所有要保存之前所有遇到if的前缀队列,对齐的空格数直接使用最后一次保存的值。而预测给当前的值直接赋值给下一行预测,需要注意的是注意结束标志endif则需要将预测的值减去一个tab赋给下一行的预测。
这样就完成了if的自动对齐。for
支持就需要在之前的if支持的机制之上进行。
但是for只需要end_for就可以,同理更简单了,只需要遇到for,添加当前的前缀到for的队列,然后下一行预测添加一个tab大小的空格,endif直接使用最后一个for队列的前缀空格,下一行进行减一个tab就可以。while 同理,也只是有一个end_while。 repeat 同理,含有until和end_repeat两个对应的key。
case
ELSE和END_CASE有一个比较麻烦的点,ELSE在if语法有相同的Key,这里就需要进行判断ELSE是属于哪一个的才能选择正确的前缀。
这里可能需要在数据结构中添加一个记录if和case当前没有结束(没有对应的end_if和end_case)的缓存队列,其中保存行号,ELSE匹配if与case最近(较大)的行号。
示例代码:
def GetAutoAlignment(self, spaceCount, content): """ 自动对齐功能标准的是需要分析器,本函数是其简化 :param preSpace: :param content: :return: """ currentSpace = spaceCount lineCount = 0 nextSpace = currentSpace newContent = [] word = [] tabSize = 4 keyDict = {"IF":[], "FOR":[], "WHILE":[], "REPEAT":[], "CASE":[]} countDict = {"IF":[0,[]], "FOR":[0,[]], "WHILE":[0,[]], "REPEAT":[0,[]], "CASE":[0,[]]} middleDict = {"ELSIF":"IF","END_IF":"IF", "END_FOR":"FOR", "END_WHILE":"WHILE", "UNTIL":"REPEAT","END_REPEAT":"REPEAT", "END_CASE":"CASE"} specialMiddleDict = {"ELSE":["IF","CASE"]} endList = ["END_IF","END_FOR","END_WHILE","END_REPEAT","END_CASE"] for line in content.split("\n"): lineCount += 1 for i in (line+"\n"): if i in [" ", "\n", ";", "("]: tempword = "".join(word).upper() word = [] if tempword == "": continue if tempword in keyDict: keyDict[tempword].append(lineCount) if tempword in countDict: countDict[tempword][0] += 1 countDict[tempword][1].append(currentSpace) nextSpace = currentSpace + tabSize elif tempword in middleDict: if countDict[middleDict[tempword]][0] != 0: tempSpace = countDict[middleDict[tempword]][1][-1] #不能立马赋值到currentSpace,影响下面赋值 if tempword in endList: countDict[middleDict[tempword]][0] -= 1 countDict[middleDict[tempword]][1].pop(-1) keyDict[middleDict[tempword]].pop(-1) nextSpace = currentSpace - tabSize currentSpace = tempSpace elif tempword in specialMiddleDict: #ELSE匹配最近的IF或者CASE recentSkey = "" recentNumber = 0 for Skey in specialMiddleDict[tempword]: if keyDict[Skey] != []: if recentSkey == "": recentSkey = Skey recentNumber = keyDict[Skey][-1] else: if recentNumber < keyDict[Skey][-1]: recentSkey = Skey if recentSkey!= "" and countDict[recentSkey][0] != 0: currentSpace = countDict[recentSkey][1][-1] break else: word.append(i) line = " "*currentSpace + line.lstrip() newContent.append(line) currentSpace = nextSpace return "\n".join(newContent) def OnAutoAlignment(self): content = self.Editor.GetSelectedText() startPos = self.Editor.GetSelectionStart() endPos = self.Editor.GetSelectionEnd() preSpace = "" for i in range(0,self.Editor.GetLineCount()): if self.Editor.GetLineSelEndPosition(i) >= startPos: lineContent = self.Editor.GetLineText(i-1) space = [] for j in lineContent: if j == " ": space.append(" ") else: preSpace = "".join(space) break break self.Editor.ReplaceSelection(self.GetAutoAlignment(len(preSpace),content))
有些可能需要自动换行:
keyList = ["OF","THEN","ELSE","END_IF;","END_CASE;","DO","EXIT;","END_FOR;", "END_WHILE;","REPEAT","UNTIL","END_REPEAT;"] reContent = "|".join(keyList) newContent = re.sub(r"(%s)([ ]*)([^\n])"%(reContent),r"\1\n\3",content)
转载地址:https://islet.blog.csdn.net/article/details/117261976 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2024年05月03日 14时15分21秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
在线录像就这么简单
2019-04-30
Win7系统提示对于目标文件系统文件过大
2019-04-30
redis使用--pattern选项遍历查询
2019-04-30
详细记录一次Tomcat服务器和Nginx服务器的缺省banner的修改全过程
2019-04-30
Linux下不同后缀的压缩包的解压命令
2019-04-30
linux命令tee
2019-04-30
linux安装docker
2019-04-30
Docker Compose安装
2019-04-30
批处理命令传递参数
2019-04-30
apache访问php文件报403权限问题
2019-04-30
Java连接access数据库demo
2019-04-30
ORA-01000: 超出打开游标的最大数 问题的分析和解决
2019-04-30
SVN环境中add命令详解
2019-04-30
SVN的提交和更新和删除
2019-04-30
SVN命令diff、mkdir、cat
2019-04-30
SVN工作副本还原命令revert
2019-04-30
SVN锁定lock和解锁unlock
2019-04-30