|
2 | 2 | * Apple Developer Reference documentation rendering functionality |
3 | 3 | */ |
4 | 4 |
|
5 | | -import type { AppleDocJSON, ContentItem, IndexContentItem, TopicSection, Variant } from "./types" |
| 5 | +import type { |
| 6 | + AppleDocJSON, |
| 7 | + ContentItem, |
| 8 | + IndexContentItem, |
| 9 | + PropertyItem, |
| 10 | + TopicSection, |
| 11 | + Variant, |
| 12 | +} from "./types" |
6 | 13 |
|
7 | 14 | interface RenderOptions { |
8 | 15 | externalOrigin?: string |
@@ -77,6 +84,16 @@ export async function renderFromJSON( |
77 | 84 | ) |
78 | 85 | } |
79 | 86 |
|
| 87 | + // Add properties (used by object/dictionary pages in data docs) |
| 88 | + const propertiesSection = jsonData.primaryContentSections.find((s) => s.kind === "properties") |
| 89 | + if (propertiesSection?.items) { |
| 90 | + markdown += renderProperties( |
| 91 | + propertiesSection.items, |
| 92 | + jsonData.references, |
| 93 | + options.externalOrigin, |
| 94 | + ) |
| 95 | + } |
| 96 | + |
80 | 97 | // Add content sections |
81 | 98 | const contentSections = jsonData.primaryContentSections.filter((s) => s.kind === "content") |
82 | 99 | for (const section of contentSections) { |
@@ -242,6 +259,60 @@ function renderParameters( |
242 | 259 | return markdown |
243 | 260 | } |
244 | 261 |
|
| 262 | +/** |
| 263 | + * Render properties section for data dictionary pages. |
| 264 | + */ |
| 265 | +function renderProperties( |
| 266 | + properties: PropertyItem[], |
| 267 | + references?: Record<string, ContentItem>, |
| 268 | + externalOrigin?: string, |
| 269 | +): string { |
| 270 | + if (properties.length === 0) return "" |
| 271 | + |
| 272 | + let markdown = "## Properties\n\n" |
| 273 | + |
| 274 | + for (const property of properties) { |
| 275 | + if (!property.name) continue |
| 276 | + |
| 277 | + const typeText = renderPropertyType(property.type, references, externalOrigin) |
| 278 | + const requiredText = property.required === true ? "required" : "optional" |
| 279 | + const metadata = [typeText, requiredText].filter(Boolean) |
| 280 | + const headingSuffix = metadata.length > 0 ? ` *(${metadata.join(", ")})*` : "" |
| 281 | + markdown += `### \`${property.name}\`${headingSuffix}\n\n` |
| 282 | + |
| 283 | + if (property.content && Array.isArray(property.content)) { |
| 284 | + markdown += `${renderContentArray(property.content, references, 0, externalOrigin)}` |
| 285 | + } |
| 286 | + |
| 287 | + const allowedValues = property.attributes?.find((a) => a.kind === "allowedValues")?.values |
| 288 | + if (allowedValues && allowedValues.length > 0) { |
| 289 | + const possibleValues = allowedValues.map((value) => `\`${value}\``).join(", ") |
| 290 | + markdown += `Possible Values: ${possibleValues}\n\n` |
| 291 | + } |
| 292 | + } |
| 293 | + |
| 294 | + return markdown |
| 295 | +} |
| 296 | + |
| 297 | +function renderPropertyType( |
| 298 | + type: Array<{ text?: string; kind?: string; identifier?: string }> | undefined, |
| 299 | + references?: Record<string, ContentItem>, |
| 300 | + externalOrigin?: string, |
| 301 | +): string { |
| 302 | + if (!type || type.length === 0) return "" |
| 303 | + |
| 304 | + return type |
| 305 | + .map((part) => { |
| 306 | + if (part.kind === "typeIdentifier" && part.identifier && part.text) { |
| 307 | + const url = convertIdentifierToURL(part.identifier, references, externalOrigin) |
| 308 | + return url ? `[${part.text}](${url})` : part.text |
| 309 | + } |
| 310 | + return part.text || "" |
| 311 | + }) |
| 312 | + .join("") |
| 313 | + .trim() |
| 314 | +} |
| 315 | + |
245 | 316 | /** |
246 | 317 | * Render main content sections |
247 | 318 | */ |
|
0 commit comments