Skip to content

Commit 125ea3c

Browse files
committed
[General] Add function to generate HTML with hljs style classes
1 parent 4f015b7 commit 125ea3c

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

Sources/classdumpctl/main.m

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,68 @@ static void printUsage(const char *progname) {
109109
return build;
110110
}
111111

112+
static NSString *sanitizeForHTML(NSString *input) {
113+
NSMutableString *build = [NSMutableString string];
114+
// thanks to https://www.w3.org/International/questions/qa-escapes#use
115+
NSDictionary<NSString *, NSString *> *replacementMap = @{
116+
@"<": @"&lt;",
117+
@">": @"&gt;",
118+
@"&": @"&amp;",
119+
@"\"": @"&quot;",
120+
@"'": @"&apos;",
121+
};
122+
[input enumerateSubstringsInRange:NSMakeRange(0, input.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
123+
[build appendString:(replacementMap[substring] ?: substring)];
124+
}];
125+
return build;
126+
}
127+
128+
static NSString *hljsHtmlForSemanticString(CDSemanticString *const semanticString) {
129+
NSMutableString *build = [NSMutableString string];
130+
// https://highlightjs.readthedocs.io/en/latest/css-classes-reference.html
131+
[semanticString enumerateLongestEffectiveRangesUsingBlock:^(NSString *string, CDSemanticType type) {
132+
NSString *htmlCls = nil;
133+
switch (type) {
134+
case CDSemanticTypeComment:
135+
htmlCls = @"hljs-comment";
136+
break;
137+
case CDSemanticTypeKeyword:
138+
htmlCls = @"hljs-keyword";
139+
break;
140+
case CDSemanticTypeVariable:
141+
htmlCls = @"hljs-variable";
142+
break;
143+
case CDSemanticTypeRecordName:
144+
htmlCls = @"hljs-type";
145+
break;
146+
case CDSemanticTypeClass:
147+
// hljs-class is deprecated
148+
htmlCls = @"hljs-title class";
149+
break;
150+
case CDSemanticTypeProtocol:
151+
// hljs does not officially define `hljs-title.protocol`
152+
// however `hljs-title` is still a class that themes should style
153+
htmlCls = @"hljs-title protocol";
154+
break;
155+
case CDSemanticTypeNumeric:
156+
htmlCls = @"hljs-number";
157+
break;
158+
default:
159+
break;
160+
}
161+
if (htmlCls != nil) {
162+
[build appendString:@"<span class=\""];
163+
[build appendString:htmlCls];
164+
[build appendString:@"\">"];
165+
}
166+
[build appendString:sanitizeForHTML(string)];
167+
if (htmlCls != nil) {
168+
[build appendString:@"</span>"];
169+
}
170+
}];
171+
return build;
172+
}
173+
112174
static NSString *linesForSemanticStringColorMode(CDSemanticString *const semanticString, CDOutputColorMode const colorMode, BOOL const isOutputTTY) {
113175
BOOL shouldColor = NO;
114176
switch (colorMode) {

0 commit comments

Comments
 (0)