AvalonEdit:是否可以突出显示此语法? [英] AvalonEdit: is it possible to highlight this syntax?

查看:272
本文介绍了AvalonEdit:是否可以突出显示此语法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的语言"(类似于模板语言和简单的标记语言,例如BBcode-基本上是带有某些变量,标签和类似功能的普通文本),我想强调一下它的语法.

I have a simple "language" (similar to template languages and simple markup languages such as BBcode — basically it's just normal text with some variables, tags and similar features) and I want to highlight its syntax.

这就是我坚持的东西.

Here is the thing I am stuck with.

有些变量,它们用 $ 符号( $ var1 $ )括起来.我用此规则突出显示它们:

There are variables, they are enclosed with $ sign ($var1$). I highlight them with this rule:

<RuleSet name="VariableSet">
    <Rule color="Variable">
        \$\S+?\$
    </Rule>
</RuleSet>

变量周围的某些区域可以用 {} 字符包围.

Some area around a variable can be surrounded with { } characters.

换句话说:某些变量可以有其区域",它从变量前的第一个 {开始,到变量后的第一个} 结束.多个变量不能在一个区域中,因此在{ $var1$ $var2$ }之类的情况下,没有任何区域,{}被视为普通字符并被忽略.它不是像C样式语言中的函数和本地作用域那样的作用域.

In other words: some variables can have its "region", it starts from the first { before the variable and ends at the first } after the variable. Multiple variables can't be in one region, so in cases like { $var1$ $var2$ } there is no any regions, { } are treated like normal characters and ignored. It is not a scope like function and local scopes in C-style languages.

这里是一个例子:

[b]lorem ipsum[/b] $var0$ dolor sit amet, consectetur adipisicing elit, sed do 
eiusmod tempor incididunt ut labore et dolore magna aliqua. 
{ // <— not nighlighted
{ // <— highlighted
ut enim ad minim veniam, quis nostrud 
$var1$
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
} // <— highlighted
} // <— not nighlighted

// all brackets below also should be not highlighted
duis aute { $50, 25$} irure { dolor } excepteur $var2$ sint occaecat cupidatat non
proident, sunt in culpa qui mollit anim id { est $var2$ laborum.
{ $var3$ $var4$ }

首先,我尝试使用两个Rule正则表达式解决此问题(对于{和},当然,使用这种方法不可能跳过带有<​​c4>或$var$ }的未封闭括号的情况,但这不是一个大问题) .但是我发现Rule仅在一行内起作用.

First I tried to solve this using two Rule regexps (for { and }, of course with this approach it is impossible to skip cases with unclosed brackets like { $var$ or $var$ } but that's not a big problem). However I found out that Rule works only within one line.

然后我像这样尝试Span:

<Span color="VariableAreaDelimiter" multiline="true">
    <Begin>
        \{(?!\{.*?\$\S+?\$)(?=.*?\$\S+?\$)
    </Begin>
    <End>
        \}
    </End>

    <RuleSet>
        <Import ruleSet="VariableSet"/>
        <Rule foreground="Black" fontWeight="normal">
            .
        </Rule>
    </RuleSet>
</Span>

一些问题:

  • 尽管multilinetrueBeginEnd中的正则表达式不适用于多行.因此与之不符:

  • Although the multiline is true regexps in Begin and End don't work for multiple lines. So it doesn't match this:

{
$var$

  • 如果没有右括号,则跨度将占用所有内容,直到文档末尾.这就是为什么我添加.规则.

    推荐答案

    使用AvalonEdit的突出显示引擎基本上是不可能的.

    This is fundamentally impossible with AvalonEdit's highlighting engine.

    引擎基于行,您无法执行任何多行匹配.将信息从一行传送到另一行的唯一方法是打开一个跨度-高亮引擎维护的唯一状态是当前打开的跨度的堆栈.

    The engine is line-based, you cannot perform any multi-line matches. The only way to carry information from one line to the next is by opening a span -- the only state maintained by the highlighting engine is the stack of currently open spans.

    突出显示引擎的设计方式是允许增量更新(这对于大文件的性能至关重要).如果更改一行中的文本,则仅更新该一行.如果此更新导致行尾的跨度堆栈发生更改,则以下行也会被更新(但仅当它们位于文本区域的可见部分时,否则它们的更新将延迟到用户向下滚动时) ).

    The highlighting engine is designed this way to allow for incremental updates (which is critical for performance with large files). If you change text in a line, only that single line is updated. If this update leads to a change in the span stack at the end of the line, the following lines are updated as well (but only if they are in the visible portion of the text area - otherwise their update is delayed until the user scrolls down).

    一个可能的解决方案是实现自己的IVisualLineTransformer而不是使用语法突出显示引擎.这是一个示例实现,突出显示单词"AvalonEdit"的所有出现:

    A possible solution is to implement your own IVisualLineTransformer instead of using the syntax highlighting engine. Here is an example implementation that highlights all occurrences of the word 'AvalonEdit':

    public class ColorizeAvalonEdit : DocumentColorizingTransformer
    {
        protected override void ColorizeLine(DocumentLine line)
        {
            int lineStartOffset = line.Offset;
            string text = CurrentContext.Document.GetText(line);
            int start = 0;
            int index;
            while ((index = text.IndexOf("AvalonEdit", start, StringComparison.Ordinal)) >= 0) {
                base.ChangeLinePart(
                    lineStartOffset + index, // startOffset
                    lineStartOffset + index + 10, // endOffset
                    (VisualLineElement element) => {
                        // This lambda gets called once for every VisualLineElement
                        // between the specified offsets.
                        Typeface tf = element.TextRunProperties.Typeface;
                        // Replace the typeface with a modified version of
                        // the same typeface
                        element.TextRunProperties.SetTypeface(new Typeface(
                            tf.FontFamily,
                            FontStyles.Italic,
                            FontWeights.Bold,
                            tf.Stretch
                        ));
                    });
                start = index + 1; // search for next occurrence
            }
        }
    }
    
    // Usage:
    textEditor.TextArea.TextView.LineTransformers.Add(new ColorizeAvalonEdit());
    

    这篇关于AvalonEdit:是否可以突出显示此语法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆