1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
"""Font list rendering and formatting utilities.
This module transforms font metadata into user-friendly output formats.
It handles both human-readable text output and machine-readable JSON,
with configurable display options for different use cases.
The renderer focuses on presenting font lists cleanly, handling duplicates,
sorting, and providing flexible formatting choices.
Typical usage:
fonts = get_installed_fonts()
options = ListRenderOptions(show_path=True, sorted_output=True)
result = render_list_output(fonts, options)
print("\\n".join(result.lines))
"""
"""Configuration for font list output formatting.
These options control how font lists are displayed, allowing
customization for different use cases from debugging to user interfaces.
Attributes:
show_path: Include file paths in output (default: name only)
show_name: Include font names alongside paths when both are shown
sorted_output: Sort results alphabetically and remove duplicates
json_output: Generate machine-readable JSON instead of text lines
Note:
- When show_path is False, only font names are shown
- When show_path is True and show_name is False, only paths are shown
- When both are True, format is "path::name"
- json_output implies sorting and deduplication
"""
: = False
: = False
: = False
: = False
"""Container for rendered font list output.
Provides a unified interface for both text and JSON output formats,
with convenient properties for accessing the data in the appropriate type.
The payload type depends on the kind:
- "lines": List[str] - one font per line
- "json": str - JSON formatted representation
"""
"""Initialize with output kind and payload.
Args:
kind: Output format type ("lines" or "json")
payload: Formatted output data
"""
=
=
"""Check if this is JSON output."""
return ==
"""Get output as list of text lines.
Raises:
AssertionError: If this render result is not "lines" type
"""
assert == ,
return # type: ignore[return-value]
"""Get output as JSON string.
Raises:
AssertionError: If this render result is not "json" type
"""
assert == ,
return # type: ignore[return-value]
"""Extract and normalize font file path from font metadata.
Font data structures can store paths in different locations:
- Direct "path" field for simple structures
- Nested "source.path" for more complex data
Normalizes to a canonical path string for comparison.
Args:
font: Font metadata dictionary containing path information
Returns:
Normalized absolute path string, empty string if no path found
"""
= or
return
"""Remove duplicate fonts based on file paths (case-insensitive).
Deduplication is crucial for clean output because:
- Font systems may register the same font multiple times
- Collection files (.ttc/.otc) create multiple entries
- Different fonts can have the same name but different paths
Uses lowercased normalized paths to handle case differences
across file systems and operating systems.
Args:
fonts: List of font metadata dictionaries to deduplicate
Returns:
List of unique font entries, preserving first occurrence order
"""
=
: =
=
continue # Skip entries without path information
continue # Skip duplicate paths
return
"""Render a list of fonts according to specified output options.
This is the main entry point for font list formatting. It handles:
- Sorting and deduplication based on options
- Format selection (lines vs JSON)
- Flexible display formats (path-only, name-only, or combined)
- Post-processing to ensure clean, non-redundant output
The rendering logic follows these priorities:
1. JSON format when requested (includes automatic sorting/deduping)
2. Text lines with path/name separation based on show_* flags
3. Final deduplication for path-only output when sorted
Args:
fonts: List of font metadata dictionaries to render
opts: Configuration options for output formatting
Returns:
ListRender object containing formatted output in requested format
Example:
>>> fonts = [{"path": "/System/Library/Arial.ttf", "postscript_name": "ArialMT"}]
>>> opts = ListRenderOptions(show_path=True, show_name=True)
>>> result = render_list_output(fonts, opts)
>>> result.is_json
False
>>> result.lines[0]
'/System/Library/Arial.ttf::ArialMT'
"""
=
= or
=
=
= or not
=
return
: =
=
= or or
: =
: | None = None
continue
=
=
return