簡體   English   中英

具有自定義關鍵字列表的語法突出顯示文本

[英]Syntax-highlighting Text With a Custom List of Keywords

我正在開發macOS應用程序。 我需要語法高亮顯示放置在TextView( NSTextView )上並帶有所選單詞列表的文本。 為簡單起見,我實際上是在iPhone Simulator上測試相同的功能。 無論如何,要突出顯示的單詞列表都是數組的形式。 以下是我所擁有的。

func HighlightText {
    let tagArray = ["let","var","case"]
    let style = NSParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle
    style.alignment = NSTextAlignment.Left
    let words = textView.string!.componentsSeparatedByString(" ") // textView.text (UITextView) or textView.string (NSTextView)
    let attStr = NSMutableAttributedString()
    for i in 0..<words.count {
        let word = words[i]
        if HasElements.containsElements(tagArray,text: word,ignore: true) {
            let attr = [
                NSForegroundColorAttributeName: syntaxcolor,
                NSParagraphStyleAttributeName: style,
                ]
            let str = (i != words.count-1) ? NSAttributedString(string: word.stringByAppendingString(" "), attributes: attr) : NSAttributedString(string: word, attributes: attr)
            attStr.appendAttributedString(str)
        } else {
            let attr = [
                NSForegroundColorAttributeName: NSColor.blackColor(),
                NSParagraphStyleAttributeName: style,
                ]
            let str = (i != words.count-1) ? NSAttributedString(string: word.stringByAppendingString(" "), attributes: attr) : NSAttributedString(string: word, attributes: attr)
            attStr.appendAttributedString(str)
        }
    }
    textView.textStorage?.setAttributedString(attStr)
}

class HasElements {
    static func containsElements(array:Array<String>,text:String,ignore:Bool) -> Bool {
        var has = false
        for str in array {
            if str == text {
                    has = true
                }
        }
        return has
    }
}

這里的簡單方法是將整個文本字符串分成帶有空格(“”)的單詞,並將每個單詞放入一個數組(單詞)中。 containsElements函數僅告訴您所選單詞是否包含數組(tagArray)中的關鍵字之一。 如果返回true,則將單詞放入帶有突出顯示顏色的NSMutableAttributedString中。 否則,將其放入具有純色的相同屬性字符串中。

這種簡單方法的問題在於,一個單獨的單詞將最后一個單詞和/ n與下一個單詞放在一起。 例如,如果我有一個像

let base = 3
let power = 10
var answer = 1

,因為代碼將3放在一起,因此僅第一個“ let”將突出顯示,而下一個將像“ 3 \\ nlet”那樣放在一起。 如果我使用快速枚舉分隔包含\\ n的任何單詞,則代碼將無法很好地檢測到每個新段落。 感謝您提出的改善建議。 僅供參考,我將使該主題對macOS和iOS開放。

Muchos感謝

幾個不同的選擇。 字符串具有一個稱為componentsSeparatedByCharactersInSet的函數,該函數使您可以按定義的字符集進行分隔。 不幸的是,這不起作用,因為您想用\\n分隔多個字符。

您可以將單詞分開兩次。

let firstSplit = textView.text!.componentsSeparatedByString(" ")
var words = [String]()
for word in firstSplit {
    let secondSplit = word.componentsSeparatedByString("\n")
    words.appendContentsOf(secondSplit)
}

但是這樣您對換行符就沒有任何感覺了。您需要將它們重新添加回去。

最后,最簡單的方法就是:

let newString = textView.text!.stringByReplacingOccurrencesOfString("\n", withString: "\n ")
let words = newString.componentsSeparatedByString(" ")

因此,基本上您可以添加自己的空間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM