Skip to content

Commit 75ba751

Browse files
author
Jesse Haigh
committed
update JSON structure for extensibility
1 parent f18f93c commit 75ba751

File tree

4 files changed

+251
-47
lines changed

4 files changed

+251
-47
lines changed

Sources/SwiftDocC/Checker/Checkers/InvalidCodeBlockOption.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ internal struct InvalidCodeBlockOption: Checker {
6363
// code property ends in a newline. this gives us a bogus extra line.
6464
let lineCount: Int = codeBlock.code.split(omittingEmptySubsequences: false, whereSeparator: { $0.isNewline }).count - 1
6565

66-
guard let indices = RenderBlockContent.CodeBlockOptions.parseCodeBlockOptionsArray(value) else {
66+
let indices = RenderBlockContent.CodeBlockOptions.parseCodeBlockOptionsArray(value)
67+
68+
if !value.isEmpty, indices.isEmpty {
6769
let diagnostic = Diagnostic(source: sourceFile, severity: .warning, range: codeBlock.range, identifier: "org.swift.docc.InvalidCodeBlockOption", summary: "Could not parse \(token.rawValue.singleQuoted) indices from \(value.singleQuoted). Expected an integer (e.g. 3) or an array (e.g. [1, 3, 5])")
6870
problems.append(Problem(diagnostic: diagnostic, possibleSolutions: []))
6971
return

Sources/SwiftDocC/Model/Rendering/Content/RenderBlockContent.swift

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,24 @@ public enum RenderBlockContent: Equatable {
139139
public struct CodeBlockOptions: Equatable {
140140
public var language: String?
141141
public var copyToClipboard: Bool
142-
public var wrap: Int
143-
public var highlight: [Int]
144142
public var showLineNumbers: Bool
145-
public var strikeout: [Int]
143+
public var wrap: Int
144+
public var lineAnnotations: [LineAnnotation]
145+
146+
public struct Position: Equatable, Codable {
147+
var line: Int
148+
var character: Int?
149+
}
150+
151+
public struct Range: Equatable, Codable {
152+
var start: Position
153+
var end: Position
154+
}
155+
156+
public struct LineAnnotation: Equatable, Codable {
157+
var style: String
158+
var range: Range
159+
}
146160

147161
public enum OptionName: String, CaseIterable {
148162
case _nonFrozenEnum_useDefaultCase
@@ -166,10 +180,9 @@ public enum RenderBlockContent: Equatable {
166180
public init() {
167181
self.language = ""
168182
self.copyToClipboard = true
169-
self.wrap = 0
170-
self.highlight = []
171183
self.showLineNumbers = false
172-
self.strikeout = []
184+
self.wrap = 0
185+
self.lineAnnotations = []
173186
}
174187

175188
public init(parsingLanguageString language: String?) {
@@ -186,27 +199,53 @@ public enum RenderBlockContent: Equatable {
186199
self.wrap = 0
187200
}
188201

189-
if let highlightString = tokens.first(where: { $0.name == .highlight })?.value,
190-
let highlightValue = Self.parseCodeBlockOptionsArray(highlightString) {
191-
self.highlight = highlightValue
192-
} else {
193-
self.highlight = []
202+
var annotations: [LineAnnotation] = []
203+
204+
if let highlightString = tokens.first(where: { $0.name == .highlight })?.value {
205+
let highlightValue = Self.parseCodeBlockOptionsArray(highlightString)
206+
for line in highlightValue {
207+
let pos = Position(line: line, character: nil)
208+
let range = Range(start: pos, end: pos)
209+
annotations.append(LineAnnotation(style: "highlight", range: range))
210+
}
194211
}
195212

196-
if let strikeoutString = tokens.first(where: { $0.name == .strikeout })?.value,
197-
let strikeoutValue = Self.parseCodeBlockOptionsArray(strikeoutString) {
198-
self.strikeout = strikeoutValue
199-
} else {
200-
self.strikeout = []
213+
if let strikeoutString = tokens.first(where: { $0.name == .strikeout })?.value {
214+
let strikeoutValue = Self.parseCodeBlockOptionsArray(strikeoutString)
215+
for line in strikeoutValue {
216+
let pos = Position(line: line, character: nil)
217+
let range = Range(start: pos, end: pos)
218+
annotations.append(LineAnnotation(style: "strikeout", range: range))
219+
}
201220
}
221+
222+
self.lineAnnotations = annotations
202223
}
203224

204-
public init(copyToClipboard: Bool, wrap: Int, highlight: [Int], strikeout: [Int], showLineNumbers: Bool) {
225+
public init(copyToClipboard: Bool, showLineNumbers: Bool, wrap: Int, highlight: [Int], strikeout: [Int]) {
205226
self.copyToClipboard = copyToClipboard
227+
self.showLineNumbers = showLineNumbers
206228
self.wrap = wrap
207-
self.highlight = highlight
229+
230+
var annotations: [LineAnnotation] = []
231+
for line in highlight {
232+
let pos = Position(line: line, character: nil)
233+
let range = Range(start: pos, end: pos)
234+
annotations.append(LineAnnotation(style: "highlight", range: range))
235+
}
236+
for line in strikeout {
237+
let pos = Position(line: line, character: nil)
238+
let range = Range(start: pos, end: pos)
239+
annotations.append(LineAnnotation(style: "strikeout", range: range))
240+
}
241+
self.lineAnnotations = annotations
242+
}
243+
244+
public init(copyToClipboard: Bool, showLineNumbers: Bool, wrap: Int, lineAnnotations: [LineAnnotation]) {
245+
self.copyToClipboard = copyToClipboard
208246
self.showLineNumbers = showLineNumbers
209-
self.strikeout = strikeout
247+
self.wrap = wrap
248+
self.lineAnnotations = lineAnnotations
210249
}
211250

212251
/// A function that parses array values on code block options from the language line string
@@ -863,7 +902,7 @@ extension RenderBlockContent.Table: Codable {
863902
extension RenderBlockContent: Codable {
864903
private enum CodingKeys: CodingKey {
865904
case type
866-
case inlineContent, content, caption, style, name, syntax, code, level, text, items, media, runtimePreview, anchor, summary, example, metadata, start, copyToClipboard, wrap, highlight, strikeout, showLineNumbers
905+
case inlineContent, content, caption, style, name, syntax, code, level, text, items, media, runtimePreview, anchor, summary, example, metadata, start, copyToClipboard, showLineNumbers, wrap, lineAnnotations
867906
case request, response
868907
case header, rows
869908
case numberOfColumns, columns
@@ -887,13 +926,12 @@ extension RenderBlockContent: Codable {
887926
case .codeListing:
888927
let copy = FeatureFlags.current.isExperimentalCodeBlockAnnotationsEnabled
889928
let options: CodeBlockOptions?
890-
if !Set(container.allKeys).isDisjoint(with: [.copyToClipboard, .wrap, .highlight, .strikeout, .showLineNumbers]) {
929+
if !Set(container.allKeys).isDisjoint(with: [.copyToClipboard, .showLineNumbers, .wrap, .lineAnnotations]) {
891930
options = try CodeBlockOptions(
892931
copyToClipboard: container.decodeIfPresent(Bool.self, forKey: .copyToClipboard) ?? copy,
932+
showLineNumbers: container.decodeIfPresent(Bool.self, forKey: .showLineNumbers) ?? false,
893933
wrap: container.decodeIfPresent(Int.self, forKey: .wrap) ?? 0,
894-
highlight: container.decodeIfPresent([Int].self, forKey: .highlight) ?? [],
895-
strikeout: container.decodeIfPresent([Int].self, forKey: .strikeout) ?? [],
896-
showLineNumbers: container.decodeIfPresent(Bool.self, forKey: .showLineNumbers) ?? false
934+
lineAnnotations: container.decodeIfPresent([CodeBlockOptions.LineAnnotation].self, forKey: .lineAnnotations) ?? []
897935
)
898936
} else {
899937
options = nil
@@ -1007,10 +1045,9 @@ extension RenderBlockContent: Codable {
10071045
try container.encode(l.code, forKey: .code)
10081046
try container.encodeIfPresent(l.metadata, forKey: .metadata)
10091047
try container.encodeIfPresent(l.options?.copyToClipboard, forKey: .copyToClipboard)
1010-
try container.encodeIfPresent(l.options?.wrap, forKey: .wrap)
1011-
try container.encodeIfPresent(l.options?.highlight, forKey: .highlight)
1012-
try container.encodeIfPresent(l.options?.strikeout, forKey: .strikeout)
10131048
try container.encodeIfPresent(l.options?.showLineNumbers, forKey: .showLineNumbers)
1049+
try container.encodeIfPresent(l.options?.wrap, forKey: .wrap)
1050+
try container.encodeIfPresent(l.options?.lineAnnotations, forKey: .lineAnnotations)
10141051
case .heading(let h):
10151052
try container.encode(h.level, forKey: .level)
10161053
try container.encode(h.text, forKey: .text)

Sources/SwiftDocC/SwiftDocC.docc/Resources/RenderNode.spec.json

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,43 @@
781781
}
782782
}
783783
},
784+
"LineAnnotation": {
785+
"type": "object",
786+
"properties": {
787+
"style": {
788+
"type": "string",
789+
"enum": ["highlight", "strikeout"]
790+
},
791+
"range": {
792+
"$ref": "#/components/schemas/CharacterRange"
793+
}
794+
}
795+
},
796+
"CharacterRange": {
797+
"type": "object",
798+
"properties": {
799+
"start": {
800+
"$ref": "#/components/schemas/Position"
801+
},
802+
"end": {
803+
"$ref": "#/components/schemas/Position"
804+
}
805+
}
806+
},
807+
"Position": {
808+
"type": "object",
809+
"properties": {
810+
"line": {
811+
"type": "integer"
812+
},
813+
"character": {
814+
"type": "integer"
815+
}
816+
},
817+
"required": [
818+
"line"
819+
]
820+
},
784821
"CodeListing": {
785822
"type": "object",
786823
"required": [
@@ -815,16 +852,10 @@
815852
"wrap": {
816853
"type": "integer"
817854
},
818-
"highlight": {
819-
"type": "array",
820-
"items": {
821-
"type": "integer"
822-
}
823-
},
824-
"strikeout": {
855+
"lineAnnotations": {
825856
"type": "array",
826857
"items": {
827-
"type": "integer"
858+
"$ref": "#/components/schemas/LineAnnotation"
828859
}
829860
}
830861
}

0 commit comments

Comments
 (0)