Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Sources/SwiftyMonaco/EditorMarker.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// EditorMarker.swift
// SwiftyMonaco
//
// Created by Patric Dubois on 22.03.26.
//

public struct EditorMarker: Equatable {
public enum Severity: String,Equatable {
case error, warning

}
public let severity: Severity
public let message: String
public let startLine: Int // 1-based
public let endLine: Int // 1-based

public init(severity: Severity, message: String, startLine: Int, endLine: Int) {
self.severity = severity
self.message = message
self.startLine = startLine
self.endLine = endLine
}
}
32 changes: 32 additions & 0 deletions Sources/SwiftyMonaco/Highlighting/Errors.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// Errors.swift
// SwiftyMonaco
//
// Created by Patric Dubois on 17.03.26.
//

import Foundation
enum Errors : LocalizedError {
case noWebView,
unsupportedType,
noURL,
javascriptEvaluationFailed(String),
webViewNotAvailable,
unsupportedJavascriptReturnType
var errorDescription: String? {
switch self {
case .noWebView:
return "No webview found"
case .unsupportedType:
return "Unsupported type (supported types are: Array, Bool, Dictionary, Double, Data(UTF8), Date, String, URL)"
case .noURL:
return "No URL set for HTMLTeststep"
case .webViewNotAvailable:
return "Webview not initialized, please file a bug"
case .unsupportedJavascriptReturnType:
return "Unsupported type (supported types are: Array, Bool, Dictionary, Double, Data(UTF8), Date, String, URL )"
case .javascriptEvaluationFailed(let message):
return "JavaScript evaluation failed: \(message)"
}
}
}
73 changes: 73 additions & 0 deletions Sources/SwiftyMonaco/Highlighting/LanguageSupportList.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// MonacoLanguages.swift
// SwiftyMonaco
//
// Created by Patric Dubois on 17.03.26.
//
import Foundation


/// LanguageSupportList
/// The Monaco editor comes with a list of predefined languages (support for code completions and syntax highlighting.
/// The SwiftyMonaco package comes with an additional list of predefined languages, which supports custom syntax highlighting
/// Adopters of this package may include further Language support.
/// Each of the three may override the definitions of the other.
/// The flags on this struct define how definitions are composed to hold a unique list of LanguageSupport definitions.
/// Predefined settings:
/// - include all monaco editor definitions as their support is proven.
/// - SwiftyMonaco-predefined-Settings are not taken into account as they have no additional functionality and serve more as an example
/// - Custom LanguageSupport will override Monaco language support which means, when you define a Monarch definition, it will be registered with the Monaco editor and override an existing definition.
public struct LanguageSupportList : Codable {


public static let javascript = """

var languages = monaco.languages.getLanguages();
var monacoLanguages = [];
for (var i = 0;i<languages.length;i++) {
const {id, aliases, mimetypes, extensions} = languages[i];
const language = {id, aliases, mimetypes, extensions};
//console.log(language);
monacoLanguages.push(language);
}
monacoLanguages;

"""
var languages : [LanguageSupport]


}
public struct LanguageSupport : Identifiable,Hashable, Codable, Comparable{
public static func < (lhs: LanguageSupport, rhs: LanguageSupport) -> Bool {
lhs.id < rhs.id
}

public static func == (lhs: LanguageSupport, rhs: LanguageSupport) -> Bool {
return lhs.id == rhs.id
}
public init(id: String, extensions: [String]?, aliases: [String]?, mimeTypes: [String]?) {
self.id = id
self.extensions = extensions
self.aliases = aliases
self.mimeTypes = mimeTypes

}
public let id : String
public let extensions : [String]?
public let aliases: [String]?
public let mimeTypes: [String]?

public var encoded : String {
do {
let jsonEncoder = JSONEncoder()
let data = try jsonEncoder.encode(self)
let text = String(data:data, encoding: .utf8) ?? ""
return text
}
catch {

return ""
}
}

}
4 changes: 3 additions & 1 deletion Sources/SwiftyMonaco/Highlighting/SyntaxHighlight.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
//

import Foundation
import UniformTypeIdentifiers

public struct SyntaxHighlight {
public struct SyntaxHighlight : Codable, Hashable {
public init(title: String, configuration: String) {
self.title = title
self.configuration = configuration
Expand All @@ -20,6 +21,7 @@ public struct SyntaxHighlight {

public var title: String
public var configuration: String

}

public extension SyntaxHighlight {
Expand Down
245 changes: 245 additions & 0 deletions Sources/SwiftyMonaco/JSONExtensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
//
// JSONExtensions.swift
// SwiftyMonaco
//
// Created by Patric Dubois on 17.03.26.
//
import Foundation

extension String {
func escapeSpecialCharacters() -> String {
var newText = self
if self.contains("This is much better"){

}
newText = newText.replacingOccurrences(of: "\"", with: "\\\"")
//newText = newText.replacingOccurrences(of: "\\", with: "\\\\")
newText = newText.replacingOccurrences(of: "\n", with: "\\n")
newText = newText.replacingOccurrences(of: "\t", with: "\\t")
newText = newText.replacingOccurrences(of: "\r", with: "\\r")
return newText
}
}

extension Any? {
public var jsonString : String {
if let text = self as? String {

return text.escapeSpecialCharacters()
}
else if let dict = self as? [String:Any?] {
return dict.jsonString
}

else if let array = self as? [Any] {
return array.jsonString
}
else if let bool = self as? Bool {
return String(bool)
}
else if let number = self as? Int {
return String(number)
}
else if let number = self as? Float {
return String(number)
}
else if let number = self as? Double {
return String(number)
}
else if let data = self as? Data {
return String(data : data, encoding: .utf8) ?? ""
}
else {
return ""
}
}


// public var arrayStringValue : String {
// if let text = self as? String {
// return text
// }
// else if let dict = self as? [String:Any] {
// return dict.arrayStringValue
// }
// else if let array = self as? [Any] {
// return array.arrayStringValue
// }
// else {
// return ""
// }
// }
}


import Foundation

public typealias JsonAny = Any?
public typealias JsonArray = [JsonAny]
public typealias JsonDictionary = [String: JsonAny]


extension JsonAny {


func toBool() -> Bool? {

switch self {
case let bool as Bool:
return bool
case let int as Int:
return int == 0 ? false : true
case let double as Double:
return double == 0 ? false : true
case let string as String:
return string == "true"

default:
return nil
}
}


func toDouble() -> Double? {
switch self {
case let double as Double:
return double
case let int as Int:
return Double(int)
default:
return nil
}
}


func toInt() -> Int? {
switch self {
case let double as Double:
return Int(double)
case let int as Int:
return int
default:
return nil
}
}


func toString() -> String? {
switch self {
case let string as String:
return string

default:
return nil
}
}
}

extension Dictionary where Key == String, Value == Any?{
public var jsonString : String {
var resultString = "{"
self.forEach { element in

resultString.append("\"")
resultString.append(element.key)
resultString.append("\"")
resultString.append(":")
if let dict = element.value as? [String: Any?] {

resultString.append(dict.jsonString)
resultString.append(",")
}
else if let dict = element.value as? [String: Any?] {

resultString.append(dict.jsonString)
resultString.append(",")
}
else if let dict = element.value as? [Any] {
resultString.append(dict.jsonString)
resultString.append(",")
}
else if let stringValue = element.value as? String {

resultString = resultString.appending("\"").appending(stringValue.escapeSpecialCharacters()).appending("\"")
resultString.append(",")
}
else if let number = element.value as? Int {
resultString = resultString.appending(String(number))
resultString.append(",")
}
else if let number = element.value as? Double {
resultString = resultString.appending(String(number))
resultString.append(",")
}
else if let bool = element.value as? Bool {
resultString = resultString.appending(String(bool))
resultString.append(",")
}


}
// das führendes Komma entfernen
if resultString.count > 1 && self.count > 0 {
let _ = resultString.removeLast()
}
resultString.append("}")
return resultString
}
}
extension Array where Element == Any {
public var jsonString : String {
var resultString = "["

self.forEach { element in
if let textElement = element as? String {
resultString.append("\"")
resultString.append(textElement.escapeSpecialCharacters())
resultString.append("\"")
resultString.append(",")
}
else if let dict = element as? [String: Any?] {
resultString.append(dict.jsonString)
resultString.append(",")
}
else if let dict = element as? [Any] {
resultString.append(dict.jsonString)
resultString.append(",")
}
else if let number = element as? Int {
resultString = resultString.appending(String(number))
resultString.append(",")
}
else if let number = element as? Double {
resultString = resultString.appending(String(number))
resultString.append(",")
}
else if let bool = element as? Bool {
resultString = resultString.appending(String(bool))
resultString.append(",")
}


}
if resultString.count > 1 && self.count > 0 {
let _ = resultString.removeLast()
}
resultString.append("]")
return resultString
}

}
extension Array where Element == JsonArray {
public var stringValue : String {
if let content = self.first {
return (content as [Any]).jsonString
}
else {
return ""
}



}

}

Loading