|
1 | | -// The Swift Programming Language |
2 | | -// https://docs.swift.org/swift-book |
| 1 | +import Foundation |
| 2 | +internal import VendoredDocC |
3 | 3 |
|
4 | | -import VendoredDocC |
| 4 | +public struct Archive { |
| 5 | + /// File path to the DocC Archive |
| 6 | + public let path: String |
5 | 7 |
|
6 | | -let metadata = Components.Schemas.Metadata( |
7 | | - bundleDisplayName: "fred", bundleIdentifier: "org.swift", |
8 | | - schemaVersion: .init(major: 1, minor: 0, patch: 0)) |
| 8 | + public init(path: String) { |
| 9 | + self.path = path |
| 10 | + } |
| 11 | + |
| 12 | + // ExampleDocs.doccarchive |
| 13 | + // ├── assets.json |
| 14 | + // ├── data |
| 15 | + // │ └── documentation |
| 16 | + // │ ├── exampledocs |
| 17 | + // │ │ └── examplearticle.json |
| 18 | + // │ └── exampledocs.json |
| 19 | + // ├── diagnostics.json ✅ (need an fixture that includes diagnostics) |
| 20 | + // ├── index |
| 21 | + // │ └── index.json ✅ (includes title, icon, and path in hierarchical tree of nodes) |
| 22 | + // │ (The index directory also contains a multi-segment LMDB database, but that doesn't |
| 23 | + // │ appear to be used by the DocC Render single-page application. It seems to focus entirely |
| 24 | + // │ on the index.json in this directory, flattening the tree structure encoded and using the |
| 25 | + // │ `path` property to identify and reference the relevant JSON files to load (RenderNode.spec.json) |
| 26 | + // ├── indexing-records.json ✅ (full text search content within a flat list of IndexingRecord) |
| 27 | + // ├── linkable-entities.json |
| 28 | + // └── metadata.json ✅ |
| 29 | + |
| 30 | + let decoder = JSONDecoder() |
| 31 | + |
| 32 | + func parseMetadata() throws -> Components.Schemas.Metadata { |
| 33 | + let metadataURL = URL(filePath: path).appending(component: "metadata").appendingPathExtension( |
| 34 | + "json") |
| 35 | + // print("metadata URL calculated at \(metadataURL.path)") |
| 36 | + |
| 37 | + let metadataBytes = try Data(contentsOf: metadataURL) |
| 38 | + let metadata = try decoder.decode(Components.Schemas.Metadata.self, from: metadataBytes) |
| 39 | + return metadata |
| 40 | + } |
| 41 | + |
| 42 | + func parseDiagnostics() throws -> Components.Schemas.Diagnostics { |
| 43 | + let diagnosticsURL = URL(filePath: path).appending(component: "diagnostics") |
| 44 | + .appendingPathExtension("json") |
| 45 | + |
| 46 | + let diagnosticsBytes = try Data(contentsOf: diagnosticsURL) |
| 47 | + let diagnostics = try decoder.decode( |
| 48 | + Components.Schemas.Diagnostics.self, from: diagnosticsBytes) |
| 49 | + return diagnostics |
| 50 | + } |
| 51 | + |
| 52 | + func parseIndexingRecords() throws -> Components.Schemas.IndexingRecords { |
| 53 | + let indexingRecordsURL = URL(filePath: path).appending(component: "indexing-records") |
| 54 | + .appendingPathExtension("json") |
| 55 | + |
| 56 | + let indexingRecordsBytes = try Data(contentsOf: indexingRecordsURL) |
| 57 | + let indexingRecords = try decoder.decode( |
| 58 | + Components.Schemas.IndexingRecords.self, from: indexingRecordsBytes) |
| 59 | + return indexingRecords |
| 60 | + } |
| 61 | + |
| 62 | + func parseIndex() throws -> Components.Schemas.RenderIndex { |
| 63 | + let indexURL = URL(filePath: path).appending(component: "index").appending(component: "index") |
| 64 | + .appendingPathExtension("json") |
| 65 | + |
| 66 | + let indexBytes = try Data(contentsOf: indexURL) |
| 67 | + let index = try decoder.decode(Components.Schemas.RenderIndex.self, from: indexBytes) |
| 68 | + return index |
| 69 | + } |
| 70 | + |
| 71 | + // recursive depth-first walk of tree of Nodes through the list provided, doing the |
| 72 | + // function stuff on each node (visitor pattern) |
| 73 | + func walkRenderIndexNodes( |
| 74 | + nodes: [Components.Schemas.Node], doing: (Components.Schemas.Node, Int) -> Void |
| 75 | + ) { |
| 76 | + for node in nodes { |
| 77 | + walkRenderIndexNodes(node: node, level: 0, doing: doing) |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + func walkRenderIndexNodes( |
| 82 | + node: Components.Schemas.Node, level: Int, doing: (Components.Schemas.Node, Int) -> Void |
| 83 | + ) { |
| 84 | + doing(node, level) |
| 85 | + if let childNodes = node.children { |
| 86 | + for n in childNodes { |
| 87 | + walkRenderIndexNodes(node: n, level: level + 1, doing: doing) |
| 88 | + } |
| 89 | + } |
| 90 | + } |
| 91 | +} |
9 | 92 |
|
10 | 93 | // JSON files to parse within a DocC Archive: |
11 | 94 | // |
|
0 commit comments