Uppercasing在AvalonEdit(Uppercasing in AvalonEdit)

2019-09-19 12:07发布

我写使用AvalonEdit电影脚本编辑器。

我扩展了DocumentLine类有一个“类型”属性,与代表无论是“字”值“对话框行”等。

我想以大写字母要写入的脚本内的特定类型的文件系(字符的名称例如)。

有没有渲染管线,让我去取文件行,改变它的外壳内的扩展点?

我试图创建一个扩展DocumentColorizingTransformer一类,但改变内壳“保护覆盖无效ColorizeLine(DocumentLine线)”的方法没有奏效。

Answer 1:

这是困难的,因为上部壳体可以改变所显示的字符和这个文档(视觉列与文件偏移量)之间的映射。

例如,单个字符“SS”(德语尖锐多个)只存在作为小写字母,并调用时被转换为两个字符的字符串“SS” string.ToUpper() 编辑此文本是棘手的,我们不能让用户只更换“S”的一个,作为底层的文件仅包含“SS”。

一个简单的解决方案是使用所述char.ToUpper()方法来代替,执行原始和大写字符之间的一对一的映射。 这将保持像“SS”不变的信件。

在AvalonEdit 4.2,只有两个转变被允许对已经产生的VisualLineElements:

  • 更改文本运行属性,例如,字体大小,文本颜色等。
  • 拆分VisualLineElement两个-这是通过在内部使用ChangeLinePart()使得属性可以用于文本部分被改变。

这意味着它是不可能做一个文本替换在colorizer,你需要实现这个使用VisualLineElementGenerator

/// <summary>
/// Makes all text after a colon (until the end of line) upper-case.
/// </summary>
public class UppercaseGenerator : VisualLineElementGenerator
{
    public override int GetFirstInterestedOffset(int startOffset)
    {
        TextDocument document = CurrentContext.Document;
        int endOffset = CurrentContext.VisualLine.LastDocumentLine.EndOffset;
        for (int i = startOffset; i < endOffset; i++) {
            char c = document.GetCharAt(i);
            if (c == ':')
                return i + 1;
        }
        return -1;
    }

    public override VisualLineElement ConstructElement(int offset)
    {
        DocumentLine line = CurrentContext.Document.GetLineByOffset(offset);
        return new UppercaseText(CurrentContext.VisualLine, line.EndOffset - offset);
    }

    /// <summary>
    /// Displays a portion of the document text, but upper-cased.
    /// </summary>
    class UppercaseText : VisualLineText
    {
        public UppercaseText(VisualLine parentVisualLine, int length) : base(parentVisualLine, length)
        {
        }

        protected override VisualLineText CreateInstance(int length)
        {
            return new UppercaseText(ParentVisualLine, length);
        }

        public override TextRun CreateTextRun(int startVisualColumn, ITextRunConstructionContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");

            int relativeOffset = startVisualColumn - VisualColumn;
            StringSegment text = context.GetText(context.VisualLine.FirstDocumentLine.Offset + RelativeTextOffset + relativeOffset, DocumentLength - relativeOffset);
            char[] uppercase = new char[text.Count];
            for (int i = 0; i < text.Count; i++) {
                uppercase[i] = char.ToUpper(text.Text[text.Offset + i]);
            }
            return new TextCharacters(uppercase, 0, uppercase.Length, this.TextRunProperties);
        }
    }
}

在AvalonEdit 4.3.0.8868,我添加的方法VisualLine.ReplaceElement() 这可以被用来替换默认VisualText与元件UppercaseText线路变压器(colorizer)内的元件。

需要注意的是,还可以实现对被显示为“SS”“SS”的支持。 对于这一点,你就必须实现自己的拷贝VisualLineText而不是只覆盖现有之一。 然后你可以使用一个可视化的长度从文件长度不同。 的GetRelativeOffsetGetVisualColumns方法将被用于提供文档和视觉坐标之间的映射。


还有另一种选择,你可以使用:小盘股。

// in the colorizer:
ChangeLinePart(start, end, e => e.TextRunProperties.SetTypographyProperties(new CapsTypography()));

// helper class
class CapsTypography : DefaultTextRunTypographyProperties
{
    public override FontCapitals Capitals {
        get { return FontCapitals.SmallCaps; }
    }
}

然而,WPF将使用支持他们的OpenType字体,只有当呈现小盘股。 在我的测试, Cambria与小盘股的工作,其他大多数字体不。 此外, SetTypographyProperties方法和DefaultTextRunTypographyProperties类需要AvalonEdit 4.3。



文章来源: Uppercasing in AvalonEdit