Skip to content

Commit 7f4283e

Browse files
author
Renatho De Carli Rosa
authored
Merge pull request #232 from Automattic/add-swift-brush-updated
Add syntax highlighting support for Swift
2 parents 76f3ec2 + 7785a8c commit 7f4283e

File tree

2 files changed

+198
-0
lines changed

2 files changed

+198
-0
lines changed

syntaxhighlighter.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ function_exists( 'parse_blocks' ) // WordPress 5.0+
150150
wp_register_script( 'syntaxhighlighter-brush-ruby', plugins_url( $this->shfolder . '/scripts/shBrushRuby.js', __FILE__ ), array( 'syntaxhighlighter-core' ), $this->agshver );
151151
wp_register_script( 'syntaxhighlighter-brush-scala', plugins_url( $this->shfolder . '/scripts/shBrushScala.js', __FILE__ ), array( 'syntaxhighlighter-core' ), $this->agshver );
152152
wp_register_script( 'syntaxhighlighter-brush-sql', plugins_url( $this->shfolder . '/scripts/shBrushSql.js', __FILE__ ), array( 'syntaxhighlighter-core' ), $this->agshver );
153+
wp_register_script( 'syntaxhighlighter-brush-swift', plugins_url( $this->shfolder . '/scripts/shBrushSwift.js', __FILE__ ), array( 'syntaxhighlighter-core' ), $this->agshver );
153154
wp_register_script( 'syntaxhighlighter-brush-vb', plugins_url( $this->shfolder . '/scripts/shBrushVb.js', __FILE__ ), array( 'syntaxhighlighter-core' ), $this->agshver );
154155
wp_register_script( 'syntaxhighlighter-brush-xml', plugins_url( $this->shfolder . '/scripts/shBrushXml.js', __FILE__ ), array( 'syntaxhighlighter-core' ), $this->agshver );
155156
wp_register_script( 'syntaxhighlighter-brush-yaml', plugins_url( $this->shfolder . '/scripts/shBrushYaml.js', __FILE__ ), array( 'syntaxhighlighter-core' ), $this->agshver );
@@ -232,6 +233,7 @@ function_exists( 'parse_blocks' ) // WordPress 5.0+
232233
'ruby' => 'ruby',
233234
'scala' => 'scala',
234235
'sql' => 'sql',
236+
'swift' => 'swift',
235237
'vb' => 'vb',
236238
'vbnet' => 'vb',
237239
'xml' => 'xml',
@@ -273,6 +275,7 @@ function_exists( 'parse_blocks' ) // WordPress 5.0+
273275
'r' => __( 'R', 'syntaxhighlighter' ),
274276
'ruby' => __( 'Ruby / Ruby on Rails', 'syntaxhighlighter' ),
275277
'scala' => __( 'Scala', 'syntaxhighlighter' ),
278+
'swift' => __( 'Swift', 'syntaxhighlighter' ),
276279
'sql' => __( 'SQL', 'syntaxhighlighter' ),
277280
'vb' => __( 'Visual Basic', 'syntaxhighlighter' ),
278281
'xml' => __( 'HTML / XHTML / XML / XSLT', 'syntaxhighlighter' ),
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
// Swift brush based on contributions by Alex Gorbatchev
2+
// https://github.com/syntaxhighlighter/brush-swift/blob/master/brush.js
3+
4+
;(function()
5+
{
6+
// CommonJS
7+
SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
8+
9+
function Brush()
10+
{
11+
function getKeywordsPrependedBy(keywords, by) {
12+
return '(?:' + keywords.replace(/^\s+|\s+$/g, '').replace(/\s+/g, '|' + by + '\\b').replace(/^/, by + '\\b') + ')\\b';
13+
}
14+
15+
function stringAdd(match, regexInfo) {
16+
var str = match[0],
17+
result = [],
18+
pos = 0,
19+
matchStart = 0,
20+
level = 0;
21+
22+
while (pos < str.length - 1) {
23+
if (level === 0) {
24+
if (str.substr(pos, 2) === "\\(") {
25+
result.push(new SyntaxHighlighter.Match(str.substring(matchStart, pos + 2), matchStart + match.index, regexInfo.css));
26+
level++;
27+
pos += 2;
28+
} else {
29+
pos++;
30+
}
31+
} else {
32+
if (str[pos] === "(") {
33+
level++;
34+
}
35+
if (str[pos] === ")") {
36+
level--;
37+
if (level === 0) {
38+
matchStart = pos;
39+
}
40+
}
41+
pos++;
42+
}
43+
}
44+
if (level === 0) {
45+
result.push(new SyntaxHighlighter.Match(str.substring(matchStart, str.length), matchStart + match.index, regexInfo.css));
46+
}
47+
48+
return result;
49+
};
50+
51+
// "Swift-native types" are all the protocols, classes, structs, enums, funcs, vars, and typealiases built into the language
52+
var swiftTypes = 'AbsoluteValuable Any AnyClass Array ArrayBound ArrayBuffer ArrayBufferType ' +
53+
'ArrayLiteralConvertible ArrayType AutoreleasingUnsafePointer BidirectionalIndex Bit ' +
54+
'BitwiseOperations Bool C CBool CChar CChar16 CChar32 CConstPointer CConstVoidPointer ' +
55+
'CDouble CFloat CInt CLong CLongLong CMutablePointer CMutableVoidPointer COpaquePointer ' +
56+
'CShort CSignedChar CString CUnsignedChar CUnsignedInt CUnsignedLong CUnsignedLongLong ' +
57+
'CUnsignedShort CVaListPointer CVarArg CWideChar Character CharacterLiteralConvertible ' +
58+
'Collection CollectionOfOne Comparable ContiguousArray ContiguousArrayBuffer DebugPrintable ' +
59+
'Dictionary DictionaryGenerator DictionaryIndex DictionaryLiteralConvertible Double ' +
60+
'EmptyCollection EmptyGenerator EnumerateGenerator Equatable ExtendedGraphemeClusterLiteralConvertible ' +
61+
'ExtendedGraphemeClusterType ExtensibleCollection FilterCollectionView FilterCollectionViewIndex ' +
62+
'FilterGenerator FilterSequenceView Float Float32 Float64 Float80 FloatLiteralConvertible ' +
63+
'FloatLiteralType FloatingPointClassification FloatingPointNumber ForwardIndex Generator ' +
64+
'GeneratorOf GeneratorOfOne GeneratorSequence Hashable HeapBuffer HeapBufferStorage ' +
65+
'HeapBufferStorageBase ImplicitlyUnwrappedOptional IndexingGenerator Int Int16 Int32 Int64 ' +
66+
'Int8 IntEncoder IntMax Integer IntegerArithmetic IntegerLiteralConvertible IntegerLiteralType ' +
67+
'Less LifetimeManager LogicValue MapCollectionView MapSequenceGenerator MapSequenceView ' +
68+
'MaxBuiltinFloatType MaxBuiltinIntegerType Mirror MirrorDisposition MutableCollection ' +
69+
'MutableSliceable ObjectIdentifier OnHeap Optional OutputStream PermutationGenerator ' +
70+
'Printable QuickLookObject RandomAccessIndex Range RangeGenerator RawByte RawOptionSet ' +
71+
'RawRepresentable Reflectable Repeat ReverseIndex ReverseRange ReverseRangeGenerator ' +
72+
'ReverseView Sequence SequenceOf SignedInteger SignedNumber Sink SinkOf Slice SliceBuffer ' +
73+
'Sliceable StaticString Streamable StridedRangeGenerator String StringElement ' +
74+
'StringInterpolationConvertible StringLiteralConvertible StringLiteralType UInt UInt16 ' +
75+
'UInt32 UInt64 UInt8 UIntMax UTF16 UTF32 UTF8 UWord UnicodeCodec UnicodeScalar Unmanaged ' +
76+
'UnsafeArray UnsafePointer UnsignedInteger Void Word Zip2 ZipGenerator2 abs advance alignof ' +
77+
'alignofValue assert bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC ' +
78+
'bridgeToObjectiveCUnconditional c contains count countElements countLeadingZeros debugPrint ' +
79+
'debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal false filter ' +
80+
'find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC ' +
81+
'isBridgedVerbatimToObjectiveC isUniquelyReferenced join lexicographicalCompare map max ' +
82+
'maxElement min minElement nil numericCast partition posix print println quickSort reduce ' +
83+
'reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith ' +
84+
'strideof strideofValue swap swift toString transcode true underestimateCount unsafeReflect ' +
85+
'withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject ' +
86+
'ßwithUnsafePointers withVaList ' +
87+
'fatalError assert assertionFailure precondition preconditionFailure ' +
88+
'Set AnyPublisher AnyCancellable sink store compactMap flatMap ObservableObject ';
89+
90+
var keywords = 'as break catch case class continue default deinit do dynamicType else enum ' +
91+
'extension fallthrough for forEach func if import in init is let new protocol ' +
92+
'return self Self static struct subscript super switch Type typealias ' +
93+
'var where while __COLUMN__ __FILE__ __FUNCTION__ __LINE__ associativity ' +
94+
'didSet get infix inout left mutating none nonmutating operator override required ' +
95+
'postfix precedence prefix right set try unowned unowned(safe) unowned(unsafe) weak willSet ' +
96+
'guard convenience defer dynamic final fileprivate private internal open public repeat throw throws rethrows unowned lazy ' +
97+
'isolated nonisolated safe unsafe some optional assignment indirect ' +
98+
// Precedence group
99+
'precedencegroup higherThan lowerThan ' +
100+
// Swift concurrency
101+
'actor associatedtype async await ';
102+
103+
var attributes = 'assignment class_protocol exported noreturn escaping NSCopying NSManaged objc nonobjc optional required auto_closure IBAction IBDesignable IBInspectable IBOutlet infix prefix postfix unknown available ' +
104+
'resultBuilder propertyWrapper autoclosure convention ' +
105+
// SwiftUI property wrappers
106+
'Binding State StateObject ObservedObject EnvironmentObject ViewBuilder Environment ScaledMetric main ' +
107+
// Swift concurrency
108+
'MainActor Sendable globalActor ';
109+
110+
var datatypes = 'char bool BOOL double float int long short id instancetype void ' +
111+
' Class IMP SEL _cmd';
112+
113+
this.regexList = [
114+
// HTML entities
115+
{
116+
regex: new RegExp('\&[a-z]+;', 'gi'),
117+
css: 'plain'
118+
},
119+
// Single line comments
120+
{
121+
regex: SyntaxHighlighter.regexLib.singleLineCComments,
122+
css: 'comments'
123+
},
124+
// Multiline comments in Swift
125+
{
126+
regex: SyntaxHighlighter.regexLib.multiLineCComments,
127+
css: 'comments'
128+
},
129+
// Nested comments are supported up to 2 levels
130+
{
131+
regex: new RegExp(/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/, 'gs'),
132+
css: 'comments'
133+
},
134+
// Multiline strings in Swift
135+
{
136+
regex: new RegExp(/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/, 'gm'),
137+
css: 'string'
138+
},
139+
// Types in Swift foundation
140+
{
141+
regex: new RegExp(this.getKeywords(datatypes), 'gm'),
142+
css: 'datatypes'
143+
},
144+
// Handle string interpolation in Swift
145+
{
146+
regex: SyntaxHighlighter.regexLib.doubleQuotedString,
147+
css: 'string',
148+
func: stringAdd
149+
},
150+
// Numeric literals in Swift
151+
{
152+
regex: new RegExp('\\b([\\d_]+(\\.[\\de_]+)?|0x[a-f0-9_]+(\\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b', 'gi'),
153+
css: 'value'
154+
},
155+
// Keywords in Swift
156+
{
157+
regex: new RegExp(this.getKeywords(keywords), 'gm'),
158+
css: 'keyword'
159+
},
160+
// Common declaration and type attributes in Swift
161+
{
162+
regex: new RegExp(getKeywordsPrependedBy(attributes, '@'), 'gm'),
163+
css: 'color1'
164+
},
165+
// Common native types in Swift
166+
{
167+
regex: new RegExp(this.getKeywords(swiftTypes), 'gm'),
168+
css: 'color2'
169+
},
170+
// UIKit/NS/Core Graphics/Core Animation/MapKit/XCFrameworks types
171+
{
172+
regex: new RegExp(/\b(?:UI|NS|CG|CA|MK|XC)[a-zA-Z0-9_]+\b/, 'g'),
173+
css: 'color2'
174+
},
175+
// Compiler directives
176+
{
177+
regex: new RegExp(/^ *#[a-zA-Z0-9_]+/, 'gm'),
178+
css: 'preprocessor'
179+
},
180+
// Any variables
181+
{
182+
regex: new RegExp('\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b', 'gi'),
183+
css: 'variable'
184+
}
185+
];
186+
}
187+
188+
Brush.prototype = new SyntaxHighlighter.Highlighter();
189+
Brush.aliases = ['swift'];
190+
191+
SyntaxHighlighter.brushes.Swift = Brush;
192+
193+
// CommonJS
194+
typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
195+
})();

0 commit comments

Comments
 (0)