我想学习如何使用textmate grammars从给定的文本中识别/提取/选择范围。
经过数小时的搜索后,我没有找到任何可供使用的python库...相反,我只是找到了一些用其他语言编写的解决方案,例如:
我对python解决方案感兴趣,并且将上述解决方案移植到python将超出范围...我认为我最好的机会将是直接尝试理解如何通过msyelf实现这些范围算法。
我想学习两种方法来自己实现(来自SublimeText API,由于代码未公开为库,因此我不能直接使用):
extract_scope(point)
:返回在给定点分配给字符的语法范围名称的范围。 scope_name(point)
:返回在给定点分配给字符的语法范围名称。此刻,我有了这个骨架(我不知道如何使用未实现的cos):
ini.json
{
"fileTypes": [
"ini",
"INI",
"inf",
"INF",
"reg",
"REG",
"lng",
"cfg",
"CFG",
"url",
"URL",
".editorconfig"
],
"name": "INI",
"patterns": [
{
"captures": {
"1": {
"name": "punctuation.definition.comment.ini"
}
},
"match": "^\\s*(;|#).*$\\n?",
"name": "comment.line.semicolon.ini"
},
{
"captures": {
"1": {
"name": "punctuation.definition.section.ini"
},
"2": {
"name": "entity.section.ini"
},
"3": {
"name": "punctuation.definition.section.ini"
}
},
"match": "^\\s*(\\[)(.*?)(\\])",
"name": "meta.tag.section.ini"
},
{
"captures": {
"1": {
"name": "meta.property.ini"
},
"10": {
"name": "comment.declarationline.semicolon.ini"
},
"2": {
"name": "punctuation.definition.quote.ini"
},
"3": {
"name": "keyword.name.ini"
},
"4": {
"name": "punctuation.definition.quote.ini"
},
"5": {
"name": "punctuation.definition.equals.ini"
},
"6": {
"name": "meta.value.ini"
},
"7": {
"name": "punctuation.definition.quote.ini"
},
"8": {
"name": "string.name.value.ini"
},
"9": {
"name": "punctuation.definition.quote.ini"
}
},
"match": "^(\\s*([\"']?)(.+?)(\\2)\\s*(=))?\\s*(([\"']?)(.*?)(\\7))\\s*(;.*)?$\\n?",
"name": "meta.declaration.ini"
}
],
"scopeName": "source.ini",
"uuid": "957acd74-6d7c-4732-a25b-5f66a1e637cd"
}
mcve.py
import json
import textwrap
from oniguruma import onigmo
from pathlib import Path
TMLANGUAGE = json.loads(Path("ini.json").read_text())
SAMPLE = textwrap.dedent("""\
[title1]
#=
a=bcd
#=
e=11
[title2]
#=e=11
""")
def scope_name(text, pt):
raise NotImplementedError
def extract_scope(text, pt):
raise NotImplementedError
if __name__ == '__main__':
for i, c in enumerate(SAMPLE):
try:
print("{:<20}{:<80}{}".format(
repr(c),
repr(extract_scope(SAMPLE, i))),
scope_name(SAMPLE, i)
)
except NotImplementedError as e:
print("{:<20}{:<80}{}".format(repr(c), "UNIMPLEMENTED", "UNIMPLEMENTED"))
想法是将Onigmo用作正则表达式引擎,就像这些tmLanguage文件使用Oniguruma一样。
为了完全理解我要在此处实现的目标,请允许我在提供的SAMPLE文本上张贴extract_scope
和scope_name
函数的输出(当它们输出时)得以实施)
'[' '[title1' source.ini meta.tag.section.ini punctuation.definition.section.ini
't' 'title1' source.ini meta.tag.section.ini entity.section.ini
'i' 'title1' source.ini meta.tag.section.ini entity.section.ini
't' 'title1' source.ini meta.tag.section.ini entity.section.ini
'l' 'title1' source.ini meta.tag.section.ini entity.section.ini
'e' 'title1' source.ini meta.tag.section.ini entity.section.ini
'1' 'title1' source.ini meta.tag.section.ini entity.section.ini
']' 'title1]' source.ini meta.tag.section.ini punctuation.definition.section.ini
'\n' '[title1]\n\n#=\n\na=bcd\n\n#=\n\ne=11\n\n\n[title2]\n\n#=e=11' source.ini
'\n' '\n' source.ini meta.declaration.ini
'#' '#=\n' source.ini comment.line.semicolon.ini punctuation.definition.comment.ini
'=' '#=\n' source.ini comment.line.semicolon.ini
'\n' '#=\n' source.ini comment.line.semicolon.ini
'\n' '\na=bcd\n\n' source.ini meta.declaration.ini
'a' 'a=' source.ini meta.declaration.ini meta.property.ini keyword.name.ini
'=' 'a=' source.ini meta.declaration.ini meta.property.ini punctuation.definition.equals.ini
'b' '=bcd' source.ini meta.declaration.ini meta.value.ini string.name.value.ini
'c' '=bcd' source.ini meta.declaration.ini meta.value.ini string.name.value.ini
'd' '=bcd' source.ini meta.declaration.ini meta.value.ini string.name.value.ini
'\n' '\na=bcd\n\n' source.ini meta.declaration.ini
'\n' '\na=bcd\n\n' source.ini meta.declaration.ini
'#' '#=\n' source.ini comment.line.semicolon.ini punctuation.definition.comment.ini
'=' '#=\n' source.ini comment.line.semicolon.ini
'\n' '#=\n' source.ini comment.line.semicolon.ini
'\n' '\ne=11\n\n\n' source.ini meta.declaration.ini
'e' 'e=' source.ini meta.declaration.ini meta.property.ini keyword.name.ini
'=' 'e=' source.ini meta.declaration.ini meta.property.ini punctuation.definition.equals.ini
'1' '=11' source.ini meta.declaration.ini meta.value.ini string.name.value.ini
'1' '=11' source.ini meta.declaration.ini meta.value.ini string.name.value.ini
'\n' '\ne=11\n\n\n' source.ini meta.declaration.ini
'\n' '\ne=11\n\n\n' source.ini meta.declaration.ini
'\n' '\ne=11\n\n\n' source.ini meta.declaration.ini
'[' '[title2' source.ini meta.tag.section.ini punctuation.definition.section.ini
't' 'title2' source.ini meta.tag.section.ini entity.section.ini
'i' 'title2' source.ini meta.tag.section.ini entity.section.ini
't' 'title2' source.ini meta.tag.section.ini entity.section.ini
'l' 'title2' source.ini meta.tag.section.ini entity.section.ini
'e' 'title2' source.ini meta.tag.section.ini entity.section.ini
'2' 'title2' source.ini meta.tag.section.ini entity.section.ini
']' 'title2]' source.ini meta.tag.section.ini punctuation.definition.section.ini
'\n' '[title1]\n\n#=\n\na=bcd\n\n#=\n\ne=11\n\n\n[title2]\n\n#=e=11' source.ini
'\n' '\n' source.ini meta.declaration.ini
'#' '#=e=11' source.ini comment.line.semicolon.ini punctuation.definition.comment.ini
'=' '#=e=11' source.ini comment.line.semicolon.ini
'e' '#=e=11' source.ini comment.line.semicolon.ini
'=' '#=e=11' source.ini comment.line.semicolon.ini
'1' '#=e=11' source.ini comment.line.semicolon.ini
'1' '#=e=11' source.ini comment.line.semicolon.ini
我选择了.ini tmLanguage,因为它似乎是最简单的tmLanguage之一,但理想情况下,我希望能够加载和使用任何类型的tmLanguage。
问题:您能同时提供scope_name
和extract_scope
函数的实现(或我自己可以实现的准确的正确解释)吗?与上述发布相比,这些实现应提供合理的相似输出。