fontist 3.0.1 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/discover-fonts.yml +76 -0
- data/.github/workflows/rake.yml +103 -8
- data/TODO.audit-docs.md +164 -0
- data/TODO.improve-docs.md +114 -0
- data/TODO.upgrade-excavate.md +107 -0
- data/docs/guide/formulas.md +37 -1
- data/docs/guide/how-it-works.md +13 -0
- data/docs/guide/platforms/windows.md +67 -0
- data/lib/fontist/errors.rb +21 -0
- data/lib/fontist/font_installer.rb +2 -0
- data/lib/fontist/formula.rb +11 -0
- data/lib/fontist/import/create_formula.rb +5 -0
- data/lib/fontist/import/formula_builder.rb +9 -0
- data/lib/fontist/import/sil_importer.rb +2 -2
- data/lib/fontist/import/windows/fod_capabilities.yml +654 -0
- data/lib/fontist/import/windows/windows_license.txt +4 -0
- data/lib/fontist/import/windows.rb +162 -0
- data/lib/fontist/import.rb +1 -0
- data/lib/fontist/import_source.rb +1 -0
- data/lib/fontist/macos/catalog/catalog_manager.rb +1 -1
- data/lib/fontist/resource.rb +5 -1
- data/lib/fontist/resources/windows_fod_resource.rb +51 -0
- data/lib/fontist/resources.rb +1 -0
- data/lib/fontist/utils/downloader.rb +4 -3
- data/lib/fontist/utils/system.rb +17 -0
- data/lib/fontist/utils/user_agent.rb +95 -0
- data/lib/fontist/utils.rb +1 -0
- data/lib/fontist/version.rb +1 -1
- data/lib/fontist/windows_fod_metadata.rb +83 -0
- data/lib/fontist/windows_import_source.rb +54 -0
- data/lib/fontist.rb +2 -0
- data/script/generate_windows_formulas.rb +24 -0
- data/script/validate_windows_fod_ci.rb +175 -0
- metadata +14 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ef31ff4d5c017fd86187db92ab8eb9c428e694731d9bb7eb9be4dadbcb7ac210
|
|
4
|
+
data.tar.gz: 87f038f05b151bb64f31fc0592d2b2b6e883414852623232c23e2cff12d37df3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bad74c88e0eeb2d2cd12fb8e7c0f9e09663c9fc98ddbebdf0ab54b8f3eb90895414fa7fc5fb699356ff590f7f1ea1cb66cce11917415ecbe9d70112bc5f312e0
|
|
7
|
+
data.tar.gz: 4c843a8d911ce97ff680fb3ac85d440e80f617982a77c82e6bc8cc6c40b32a050ff2daf50a109c73b174c7ec851e0999f4a6df77148546b9f44838b80205e83d
|
|
@@ -69,6 +69,8 @@ jobs:
|
|
|
69
69
|
version: [2022, 2025]
|
|
70
70
|
fail-fast: false
|
|
71
71
|
steps:
|
|
72
|
+
- uses: actions/checkout@v6
|
|
73
|
+
|
|
72
74
|
- name: List ALL Windows Fonts
|
|
73
75
|
shell: pwsh
|
|
74
76
|
run: |
|
|
@@ -78,6 +80,80 @@ jobs:
|
|
|
78
80
|
Write-Host "=== Total Count ==="
|
|
79
81
|
(Get-ChildItem -Path "C:\Windows\Fonts\" -Include *.ttf,*.ttc,*.otf -Recurse).Count
|
|
80
82
|
|
|
83
|
+
- name: List FOD font capabilities
|
|
84
|
+
shell: pwsh
|
|
85
|
+
run: |
|
|
86
|
+
Write-Host "=== Windows FOD Font Capabilities ==="
|
|
87
|
+
$caps = Get-WindowsCapability -Online -Name "Language.Fonts.*"
|
|
88
|
+
$caps | Format-Table -AutoSize Name, State
|
|
89
|
+
Write-Host ""
|
|
90
|
+
Write-Host "=== Summary ==="
|
|
91
|
+
$installed = ($caps | Where-Object { $_.State -eq "Installed" }).Count
|
|
92
|
+
$notPresent = ($caps | Where-Object { $_.State -eq "NotPresent" }).Count
|
|
93
|
+
$staged = ($caps | Where-Object { $_.State -eq "Staged" }).Count
|
|
94
|
+
Write-Host "Installed: $installed"
|
|
95
|
+
Write-Host "NotPresent: $notPresent"
|
|
96
|
+
Write-Host "Staged: $staged"
|
|
97
|
+
Write-Host "Total: $($caps.Count)"
|
|
98
|
+
Write-Host ""
|
|
99
|
+
Write-Host "=== Saving results ==="
|
|
100
|
+
New-Item -ItemType Directory -Force -Path artifacts | Out-Null
|
|
101
|
+
$caps | Select-Object Name, State | ConvertTo-Csv -NoTypeInformation | Out-File -FilePath artifacts/fod-capabilities.csv
|
|
102
|
+
$caps | ConvertTo-Json | Out-File -FilePath artifacts/fod-capabilities.json
|
|
103
|
+
Write-Host "Saved to artifacts/fod-capabilities.csv and artifacts/fod-capabilities.json"
|
|
104
|
+
|
|
105
|
+
- name: Cross-check FOD capabilities with our YAML
|
|
106
|
+
shell: pwsh
|
|
107
|
+
run: |
|
|
108
|
+
Write-Host "=== Cross-checking fod_capabilities.yml against live Windows ==="
|
|
109
|
+
|
|
110
|
+
# Get live capabilities from Windows
|
|
111
|
+
$liveCaps = Get-WindowsCapability -Online -Name "Language.Fonts.*"
|
|
112
|
+
$liveNames = $liveCaps | ForEach-Object { $_.Name }
|
|
113
|
+
|
|
114
|
+
# Parse our YAML capability names (simple text extraction)
|
|
115
|
+
$yamlPath = "lib/fontist/import/windows/fod_capabilities.yml"
|
|
116
|
+
$yamlContent = Get-Content $yamlPath -Raw
|
|
117
|
+
$yamlNames = [regex]::Matches($yamlContent, '^\s+"([^"]+)":', [System.Text.RegularExpressions.RegexOptions]::Multiline) |
|
|
118
|
+
ForEach-Object { $_.Groups[1].Value }
|
|
119
|
+
|
|
120
|
+
Write-Host ""
|
|
121
|
+
Write-Host "Live capabilities: $($liveNames.Count)"
|
|
122
|
+
Write-Host "YAML capabilities: $($yamlNames.Count)"
|
|
123
|
+
Write-Host ""
|
|
124
|
+
|
|
125
|
+
# Find matches
|
|
126
|
+
$matched = $yamlNames | Where-Object { $liveNames -contains $_ }
|
|
127
|
+
Write-Host "=== Matched ($($matched.Count)) ==="
|
|
128
|
+
$matched | ForEach-Object { Write-Host " OK: $_" }
|
|
129
|
+
|
|
130
|
+
# Find missing from our YAML (present on Windows but not in our file)
|
|
131
|
+
$missingFromYaml = $liveNames | Where-Object { $yamlNames -notcontains $_ }
|
|
132
|
+
if ($missingFromYaml.Count -gt 0) {
|
|
133
|
+
Write-Host ""
|
|
134
|
+
Write-Host "=== Missing from our YAML ($($missingFromYaml.Count)) ==="
|
|
135
|
+
$missingFromYaml | ForEach-Object { Write-Host " MISSING: $_" }
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# Find extra in our YAML (in our file but not on Windows)
|
|
139
|
+
$extraInYaml = $yamlNames | Where-Object { $liveNames -notcontains $_ }
|
|
140
|
+
if ($extraInYaml.Count -gt 0) {
|
|
141
|
+
Write-Host ""
|
|
142
|
+
Write-Host "=== Extra in our YAML ($($extraInYaml.Count)) ==="
|
|
143
|
+
$extraInYaml | ForEach-Object { Write-Host " EXTRA: $_" }
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
Write-Host ""
|
|
147
|
+
Write-Host "=== Cross-check complete ==="
|
|
148
|
+
|
|
149
|
+
- name: Upload FOD capability results
|
|
150
|
+
if: always()
|
|
151
|
+
uses: actions/upload-artifact@v4
|
|
152
|
+
with:
|
|
153
|
+
name: windows-fod-capabilities-${{ matrix.version }}
|
|
154
|
+
path: artifacts/
|
|
155
|
+
if-no-files-found: warn
|
|
156
|
+
|
|
81
157
|
discover-linux:
|
|
82
158
|
name: Linux fonts
|
|
83
159
|
runs-on: ubuntu-latest
|
data/.github/workflows/rake.yml
CHANGED
|
@@ -214,6 +214,104 @@ jobs:
|
|
|
214
214
|
echo " Test Complete"
|
|
215
215
|
echo "========================================================================="
|
|
216
216
|
|
|
217
|
+
- name: Test Windows FOD font installation
|
|
218
|
+
if: startsWith(matrix.os, 'windows')
|
|
219
|
+
continue-on-error: true
|
|
220
|
+
shell: pwsh
|
|
221
|
+
run: |
|
|
222
|
+
Write-Host "========================================================================="
|
|
223
|
+
Write-Host " Windows FOD (Features on Demand) Font Installation Test"
|
|
224
|
+
Write-Host "========================================================================="
|
|
225
|
+
Write-Host ""
|
|
226
|
+
Write-Host "Platform: Windows $(([System.Environment]::OSVersion.Version).ToString())"
|
|
227
|
+
Write-Host "Runner: ${{ matrix.os }}"
|
|
228
|
+
Write-Host ""
|
|
229
|
+
|
|
230
|
+
Write-Host "--- Step 1: Generate Windows FOD Formulas into formulas repo ---"
|
|
231
|
+
$formulasRepo = bundle exec ruby -e "require 'fontist'; puts Fontist.formulas_path"
|
|
232
|
+
$formulasRepo = $formulasRepo.Trim()
|
|
233
|
+
$windowsDir = Join-Path $formulasRepo "windows"
|
|
234
|
+
Write-Host "Formulas path: $formulasRepo"
|
|
235
|
+
Write-Host "Generating FOD formulas into: $windowsDir"
|
|
236
|
+
bundle exec ruby script/generate_windows_formulas.rb $windowsDir
|
|
237
|
+
$formulaCount = (Get-ChildItem -Path $windowsDir -Filter "*.yml" -ErrorAction SilentlyContinue).Count
|
|
238
|
+
Write-Host "Generated $formulaCount formula files"
|
|
239
|
+
Write-Host ""
|
|
240
|
+
|
|
241
|
+
Write-Host "--- Step 2: Rebuild formula index to include FOD formulas ---"
|
|
242
|
+
bundle exec ruby -e "require 'fontist'; Fontist::Index.rebuild; puts 'Formula index rebuilt'; f = Fontist::Formula.find('Arial Nova'); puts f ? 'Verified: Arial Nova found -> ' + f.name : 'WARNING: Arial Nova NOT found in index'"
|
|
243
|
+
if ($LASTEXITCODE -ne 0) {
|
|
244
|
+
Write-Host "WARNING: Formula index rebuild failed with exit code $LASTEXITCODE"
|
|
245
|
+
}
|
|
246
|
+
Write-Host ""
|
|
247
|
+
|
|
248
|
+
Write-Host "--- Step 2b: Verify formula index ---"
|
|
249
|
+
$indexPath = bundle exec ruby -e "require 'fontist'; puts Fontist.formula_index_path"
|
|
250
|
+
$indexPath = $indexPath.Trim()
|
|
251
|
+
Write-Host "Formula index path: $indexPath"
|
|
252
|
+
if (Test-Path $indexPath) {
|
|
253
|
+
$lineCount = (Get-Content $indexPath).Count
|
|
254
|
+
Write-Host "Formula index exists: $lineCount lines"
|
|
255
|
+
Write-Host "First 20 lines:"
|
|
256
|
+
Get-Content $indexPath -Head 20
|
|
257
|
+
} else {
|
|
258
|
+
Write-Host "WARNING: Formula index file does NOT exist at $indexPath"
|
|
259
|
+
}
|
|
260
|
+
Write-Host ""
|
|
261
|
+
|
|
262
|
+
Write-Host "--- Step 2c: Verify formula files on disk ---"
|
|
263
|
+
$formulasDir = bundle exec ruby -e "require 'fontist'; puts Fontist.formulas_path"
|
|
264
|
+
$formulasDir = $formulasDir.Trim()
|
|
265
|
+
Write-Host "Formulas directory: $formulasDir"
|
|
266
|
+
if (Test-Path $formulasDir) {
|
|
267
|
+
$ymlFiles = Get-ChildItem -Path $formulasDir -Filter "*.yml" -Recurse
|
|
268
|
+
Write-Host "Total .yml files: $($ymlFiles.Count)"
|
|
269
|
+
$ymlFiles | Select-Object -First 30 | ForEach-Object { Write-Host " $($_.FullName)" }
|
|
270
|
+
} else {
|
|
271
|
+
Write-Host "WARNING: Formulas directory does NOT exist"
|
|
272
|
+
}
|
|
273
|
+
Write-Host ""
|
|
274
|
+
|
|
275
|
+
Write-Host "--- Step 3: List FOD Font Capabilities ---"
|
|
276
|
+
$caps = Get-WindowsCapability -Online -Name "Language.Fonts.*"
|
|
277
|
+
$installed = ($caps | Where-Object { $_.State -eq "Installed" })
|
|
278
|
+
$notPresent = ($caps | Where-Object { $_.State -eq "NotPresent" })
|
|
279
|
+
Write-Host "Installed: $($installed.Count)"
|
|
280
|
+
Write-Host "NotPresent: $($notPresent.Count)"
|
|
281
|
+
Write-Host "Total: $($caps.Count)"
|
|
282
|
+
Write-Host ""
|
|
283
|
+
|
|
284
|
+
Write-Host "--- Step 4: Run Cross-Check Validation ---"
|
|
285
|
+
bundle exec ruby script/validate_windows_fod_ci.rb
|
|
286
|
+
Write-Host ""
|
|
287
|
+
|
|
288
|
+
Write-Host "--- Step 5: Install Plantagenet Cherokee via fontist (small FOD) ---"
|
|
289
|
+
Write-Host "Running: fontist install 'Plantagenet Cherokee' --accept-all-licenses"
|
|
290
|
+
bundle exec fontist install "Plantagenet Cherokee" --accept-all-licenses
|
|
291
|
+
if ($LASTEXITCODE -eq 0) {
|
|
292
|
+
Write-Host "fontist install succeeded"
|
|
293
|
+
} else {
|
|
294
|
+
Write-Host "WARNING: fontist install exited with code $LASTEXITCODE"
|
|
295
|
+
}
|
|
296
|
+
Write-Host ""
|
|
297
|
+
|
|
298
|
+
Write-Host "--- Step 6: Verify Plantagenet Cherokee via fontist list ---"
|
|
299
|
+
bundle exec fontist list "Plantagenet Cherokee"
|
|
300
|
+
Write-Host ""
|
|
301
|
+
|
|
302
|
+
Write-Host "--- Step 7: Verify font file on disk ---"
|
|
303
|
+
$path = Join-Path "C:\Windows\Fonts" "Plantc.ttf"
|
|
304
|
+
if (Test-Path $path) {
|
|
305
|
+
Write-Host " OK: Plantc.ttf"
|
|
306
|
+
} else {
|
|
307
|
+
Write-Host " MISSING: Plantc.ttf"
|
|
308
|
+
}
|
|
309
|
+
Write-Host ""
|
|
310
|
+
|
|
311
|
+
Write-Host "========================================================================="
|
|
312
|
+
Write-Host " Test Complete"
|
|
313
|
+
Write-Host "========================================================================="
|
|
314
|
+
|
|
217
315
|
- name: Upload system index as artifact
|
|
218
316
|
if: always()
|
|
219
317
|
uses: actions/upload-artifact@v4
|
|
@@ -237,17 +335,14 @@ jobs:
|
|
|
237
335
|
|
|
238
336
|
steps:
|
|
239
337
|
- name: Setup packages
|
|
240
|
-
run:
|
|
338
|
+
run: |
|
|
339
|
+
pacman -Syu --noconfirm git binutils gcc autoconf make libffi libyaml gmp ruby ruby-stdlib
|
|
241
340
|
|
|
242
341
|
- uses: actions/checkout@v4
|
|
243
342
|
|
|
244
|
-
- uses: asdf-vm/actions/install@v3
|
|
245
|
-
with:
|
|
246
|
-
tool_versions: ruby ${{ needs.prepare.outputs.default-ruby-version }}
|
|
247
|
-
|
|
248
343
|
- run: |
|
|
249
|
-
gem install bundler
|
|
250
|
-
bundle install
|
|
344
|
+
gem install --no-document --user-install bundler
|
|
345
|
+
PATH="$(ruby -e 'puts Gem.user_dir')/bin:$PATH" bundle install
|
|
251
346
|
|
|
252
347
|
- name: Test
|
|
253
|
-
run: bundle exec rake
|
|
348
|
+
run: PATH="$(ruby -e 'puts Gem.user_dir')/bin:$PATH" bundle exec rake
|
data/TODO.audit-docs.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# TODO: Documentation Audit
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Audit all Fontist Ruby gem functionality to ensure complete documentation coverage.
|
|
5
|
+
|
|
6
|
+
## Reference Files
|
|
7
|
+
- docs/guide/how-it-works.md
|
|
8
|
+
- docs/api/
|
|
9
|
+
- docs/cli/
|
|
10
|
+
- docs/guide/concepts/
|
|
11
|
+
|
|
12
|
+
**Last Updated:** 2026-03-10
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## ✅ COMPLETED
|
|
17
|
+
|
|
18
|
+
### 1. Configuration Priority System
|
|
19
|
+
Documented in `/guide/how-it-works.md`
|
|
20
|
+
|
|
21
|
+
**Priority Order (Highest to Lowest):**
|
|
22
|
+
|
|
23
|
+
| Priority | Source | Example | Notes |
|
|
24
|
+
|----------|--------|---------|-------|
|
|
25
|
+
| 1 | ENV VAR | `FONTIST_PATH=/custom` | Always wins |
|
|
26
|
+
| 2 | Config file | `~/.fontist/config.yml` | Persistent settings |
|
|
27
|
+
| 3 | CLI option | `--location user` | Per-command override |
|
|
28
|
+
| 4 | Ruby API | `Fontist.preferred_family = true` | Programmatic |
|
|
29
|
+
| 5 | Default | Built-in defaults | Fallback |
|
|
30
|
+
|
|
31
|
+
### 2. Installation Locations
|
|
32
|
+
Documented in `/guide/how-it-works.md`
|
|
33
|
+
|
|
34
|
+
| Type | Path | Managed? | Use Case |
|
|
35
|
+
|------|------|----------|----------|
|
|
36
|
+
| fontist | `~/.fontist/fonts/{formula}/` | ✅ Yes | Default, isolated |
|
|
37
|
+
| user | `~/Library/Fonts/fontist/` (macOS) | ✅ Yes | User-wide access |
|
|
38
|
+
| system | `/Library/Fonts/fontist/` (macOS) | ✅ Yes | All users |
|
|
39
|
+
|
|
40
|
+
### 3. Font Indexes
|
|
41
|
+
Documented in `/guide/how-it-works.md`
|
|
42
|
+
|
|
43
|
+
- Formula Index: Maps font names → formula files
|
|
44
|
+
- System Index: OS-installed fonts
|
|
45
|
+
- Fontist Index: Fonts installed via Fontist
|
|
46
|
+
- User Index: User-installed fonts
|
|
47
|
+
|
|
48
|
+
### 4. Formula Repository
|
|
49
|
+
Documented in `/guide/formulas.md`
|
|
50
|
+
|
|
51
|
+
- Location: `~/.fontist/versions/v4/formulas/`
|
|
52
|
+
- Git clone from `https://github.com/fontist/formulas.git`
|
|
53
|
+
- Auto-updates via `fontist update`
|
|
54
|
+
- Private repos via `fontist repo`
|
|
55
|
+
|
|
56
|
+
### 5. CLI Commands
|
|
57
|
+
All documented in `/docs/cli/`
|
|
58
|
+
|
|
59
|
+
### 6. Ruby API Classes
|
|
60
|
+
All documented in `/docs/api/`
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 🔄 IN PROGRESS
|
|
65
|
+
|
|
66
|
+
- [ ] Add configuration priority table to how-it-works.md
|
|
67
|
+
- [ ] Add managed vs non-managed location explanation
|
|
68
|
+
- [ ] Document all ENV variables in reference page
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Configuration Reference
|
|
73
|
+
|
|
74
|
+
### All Configuration Settings
|
|
75
|
+
|
|
76
|
+
| Setting | ENV VAR | Config Key | CLI Option | Default |
|
|
77
|
+
|---------|---------|------------|------------|---------|
|
|
78
|
+
| Base path | `FONTIST_PATH` | - | - | `~/.fontist` |
|
|
79
|
+
| Fonts path | - | `fonts_path` | - | `~/.fontist/fonts` |
|
|
80
|
+
| Formulas path | `FONTIST_FORMULAS_PATH` | - | `--formulas-path` | (auto) |
|
|
81
|
+
| Install location | `FONTIST_INSTALL_LOCATION` | `fonts_install_location` | `--location` | `fontist` |
|
|
82
|
+
| User fonts path | `FONTIST_USER_FONTS_PATH` | `user_fonts_path` | - | Platform default |
|
|
83
|
+
| System fonts path | `FONTIST_SYSTEM_FONTS_PATH` | `system_fonts_path` | - | Platform default |
|
|
84
|
+
| Preferred family | - | `preferred_family` | `--preferred-family` | `false` |
|
|
85
|
+
| No cache | - | - | `--no-cache` | `false` |
|
|
86
|
+
| Quiet mode | - | - | `--quiet` | `false` |
|
|
87
|
+
| Verbose | - | - | `--verbose` | `false` |
|
|
88
|
+
| Open timeout | - | `open_timeout` | - | `60` |
|
|
89
|
+
| Read timeout | - | `read_timeout` | - | `60` |
|
|
90
|
+
| Google Fonts key | `GOOGLE_FONTS_API_KEY` | `google_fonts_key` | - | `nil` |
|
|
91
|
+
| Import cache | `FONTIST_IMPORT_CACHE` | - | - | `~/.fontist/import_cache` |
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Environment Variables Reference
|
|
96
|
+
|
|
97
|
+
| Variable | Description | Default |
|
|
98
|
+
|----------|-------------|---------|
|
|
99
|
+
| `FONTIST_PATH` | Base directory for all Fontist data | `~/.fontist` |
|
|
100
|
+
| `FONTIST_FORMULAS_PATH` | Custom formulas directory | (auto) |
|
|
101
|
+
| `FONTIST_INSTALL_LOCATION` | Default install location (`fontist`, `user`, `system`) | `fontist` |
|
|
102
|
+
| `FONTIST_USER_FONTS_PATH` | Custom user fonts path | Platform default |
|
|
103
|
+
| `FONTIST_SYSTEM_FONTS_PATH` | Custom system fonts path | Platform default |
|
|
104
|
+
| `FONTIST_IMPORT_CACHE` | Import cache directory | `~/.fontist/import_cache` |
|
|
105
|
+
| `FONTIST_NO_MIRRORS` | Disable formula index mirrors | `false` |
|
|
106
|
+
| `GOOGLE_FONTS_API_KEY` | Google Fonts API key | (none) |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Managed vs Non-Managed Locations
|
|
111
|
+
|
|
112
|
+
### Managed Locations (Fontist controls)
|
|
113
|
+
- `~/.fontist/fonts/` - Always managed
|
|
114
|
+
- `~/Library/Fonts/fontist/` - Managed subdirectory
|
|
115
|
+
- `/Library/Fonts/fontist/` - Managed subdirectory
|
|
116
|
+
|
|
117
|
+
**Behavior:** Safe to replace existing fonts
|
|
118
|
+
|
|
119
|
+
### Non-Managed Locations (custom paths via ENV)
|
|
120
|
+
- `FONTIST_USER_FONTS_PATH=~/Library/Fonts` → installs directly
|
|
121
|
+
- `FONTIST_SYSTEM_FONTS_PATH=/Library/Fonts` → installs directly
|
|
122
|
+
|
|
123
|
+
**Behavior:** Uses unique filenames (`-fontist` suffix) to avoid conflicts
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Directory Structure
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
~/.fontist/
|
|
131
|
+
├── fonts/ # Installed font files
|
|
132
|
+
│ └── {formula-key}/
|
|
133
|
+
│ └── *.ttf
|
|
134
|
+
├── versions/
|
|
135
|
+
│ └── v4/
|
|
136
|
+
│ ├── formulas/ # Git clone of formulas repo
|
|
137
|
+
│ │ └── Formulas/
|
|
138
|
+
│ │ ├── roboto.yml
|
|
139
|
+
│ │ └── private/ # Custom formula repos
|
|
140
|
+
│ ├── formula_index.default_family.yml
|
|
141
|
+
│ ├── formula_index.preferred_family.yml
|
|
142
|
+
│ └── filename_index.yml
|
|
143
|
+
├── config.yml # User configuration
|
|
144
|
+
├── downloads/ # Temporary downloads
|
|
145
|
+
├── import_cache/ # Imported font cache
|
|
146
|
+
├── system_index.default_family.yml # System fonts index
|
|
147
|
+
├── fontist_index.default_family.yml # Fontist fonts index
|
|
148
|
+
└── user_index.default_family.yml # User fonts index
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Remaining Minor Gaps
|
|
154
|
+
|
|
155
|
+
- [ ] Document import system (`fontist import`) internals
|
|
156
|
+
- [ ] Document cache system internals
|
|
157
|
+
- [ ] Document formula picker algorithm
|
|
158
|
+
- [ ] Document locking mechanism (for concurrent operations)
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Status: Nearly Complete
|
|
163
|
+
**Priority:** High
|
|
164
|
+
**Notes:** Core functionality documented, minor gaps remain
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Fontist Documentation Improvement Plan
|
|
2
|
+
|
|
3
|
+
**Goal:** Achieve 100% documentation coverage of README.adoc content in docs/
|
|
4
|
+
|
|
5
|
+
**Status:** ✅ Complete
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Phase 1: Platform-Specific Guides (Critical)
|
|
10
|
+
|
|
11
|
+
### 1.1 Create macOS Platform Guide
|
|
12
|
+
- [x] Create `/docs/guide/platforms/macos.md`
|
|
13
|
+
- [x] Document supplementary fonts framework
|
|
14
|
+
- [x] Document framework versioning (Font3-Font8)
|
|
15
|
+
- [x] Document platform tags (`macos-fontX`)
|
|
16
|
+
- [x] Document version compatibility checking
|
|
17
|
+
- [x] Include macOS version → framework table
|
|
18
|
+
- [x] Add link to Fontist blog post
|
|
19
|
+
|
|
20
|
+
### 1.2 Create Windows Platform Guide
|
|
21
|
+
- [x] Create `/docs/guide/platforms/windows.md`
|
|
22
|
+
- [x] Document Windows font management differences
|
|
23
|
+
- [x] Document Windows font locations
|
|
24
|
+
- [x] Document file locking considerations
|
|
25
|
+
- [x] Document path handling
|
|
26
|
+
- [x] Document registry integration
|
|
27
|
+
- [x] Document administrator privileges
|
|
28
|
+
- [x] Include platform compatibility table
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Phase 2: Installation Improvements
|
|
33
|
+
|
|
34
|
+
### 2.1 Update Installation Guide
|
|
35
|
+
- [x] Add detailed dependency table (json, brotli, seven-zip, libmspack, ffi-libarchive-binary)
|
|
36
|
+
- [x] Add Windows RubyInstaller DevKit steps (`ridk install`)
|
|
37
|
+
- [x] Add Git as prerequisite for update/repo commands
|
|
38
|
+
- [x] Add note about native extension compilation
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Phase 3: Formula Advanced Features
|
|
43
|
+
|
|
44
|
+
### 3.1 Update Formulas Guide
|
|
45
|
+
- [x] Add `override:` key documentation (already present)
|
|
46
|
+
- [x] Add Frutiger fonts example (already present)
|
|
47
|
+
- [x] Add HTTP authentication for private repos (already present)
|
|
48
|
+
- [x] Add authorization headers example (already present)
|
|
49
|
+
- [x] Add token scope requirements (already present)
|
|
50
|
+
|
|
51
|
+
### 3.2 Update create-formula CLI
|
|
52
|
+
- [x] Add `--name-prefix` option with example (already documented)
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Phase 4: How It Works Improvements
|
|
57
|
+
|
|
58
|
+
### 4.1 Update How It Works Guide
|
|
59
|
+
- [x] Add managed vs non-managed locations section (already present)
|
|
60
|
+
- [x] Add font discovery behavior explanation (already present)
|
|
61
|
+
- [x] Add import cache environment variables (already present)
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Phase 5: Maintainer Documentation (Clearly Marked)
|
|
66
|
+
|
|
67
|
+
### 5.1 Create Maintainer Import Guide
|
|
68
|
+
- [x] Create `/docs/guide/maintainer/index.md`
|
|
69
|
+
- [x] Create `/docs/guide/maintainer/import.md`
|
|
70
|
+
- [x] Mark as "Maintainer Only" clearly
|
|
71
|
+
- [x] Document `fontist import google` command
|
|
72
|
+
- [x] Document Google Fonts API integration
|
|
73
|
+
- [x] Document import source architecture
|
|
74
|
+
- [x] Document versioned filenames
|
|
75
|
+
- [x] Document import cache Ruby API
|
|
76
|
+
|
|
77
|
+
### 5.2 Update CLI Import Reference
|
|
78
|
+
- [x] Add `fontist import google` to `/docs/cli/import.md` (already present)
|
|
79
|
+
- [x] Add maintainer-only notice
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Phase 6: Navigation Updates
|
|
84
|
+
|
|
85
|
+
### 6.1 Update VitePress Config
|
|
86
|
+
- [x] Add Platforms section to Guide sidebar
|
|
87
|
+
- [x] Add Maintainer section to Guide sidebar (collapsed)
|
|
88
|
+
- [x] Update navigation as needed
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Phase 7: Verification
|
|
93
|
+
|
|
94
|
+
### 7.1 Build and Test
|
|
95
|
+
- [x] Run `npm run build` to verify no errors
|
|
96
|
+
- [x] Run lychee link checker (manual verification with curl - lychee crashed)
|
|
97
|
+
- [x] Verify all new pages are accessible
|
|
98
|
+
- [x] Cross-check against README.adoc
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Progress Tracking
|
|
103
|
+
|
|
104
|
+
| Phase | Status | Items Done | Items Total |
|
|
105
|
+
|-------|--------|------------|-------------|
|
|
106
|
+
| 1. Platform Guides | ✅ Complete | 14 | 14 |
|
|
107
|
+
| 2. Installation | ✅ Complete | 4 | 4 |
|
|
108
|
+
| 3. Formula Features | ✅ Complete | 7 | 7 |
|
|
109
|
+
| 4. How It Works | ✅ Complete | 3 | 3 |
|
|
110
|
+
| 5. Maintainer Docs | ✅ Complete | 10 | 10 |
|
|
111
|
+
| 6. Navigation | ✅ Complete | 3 | 3 |
|
|
112
|
+
| 7. Verification | ✅ Complete | 4 | 4 |
|
|
113
|
+
|
|
114
|
+
**Total Progress: 45/45 items (100%)**
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# TODO: Fix Excavate Memory Leaks and Upgrade Fontist
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
Fontist CI tests pass but fail at the end with:
|
|
5
|
+
```
|
|
6
|
+
failed to allocate memory (NoMemoryError)
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
This happens after repeated archive extractions during test runs.
|
|
10
|
+
|
|
11
|
+
## Root Cause Analysis
|
|
12
|
+
Memory leaks in Excavate gem due to:
|
|
13
|
+
1. Temp directories not cleaned up on errors
|
|
14
|
+
2. Incorrect `ensure`/`rescue` order in `extract_and_replace` method
|
|
15
|
+
|
|
16
|
+
## Remaining Work
|
|
17
|
+
|
|
18
|
+
### 1. Fix Excavate Gem (in /Users/mulgogi/src/fontist/excavate)
|
|
19
|
+
|
|
20
|
+
#### archive.rb - Fix `extract_and_replace` method (lines 217-229)
|
|
21
|
+
Current broken code has `ensure` BEFORE `rescue` which is invalid Ruby syntax:
|
|
22
|
+
```ruby
|
|
23
|
+
def extract_and_replace(archive)
|
|
24
|
+
target = Dir.mktmpdir
|
|
25
|
+
extract_recursively(archive, target)
|
|
26
|
+
replace_archive_with_contents(archive, target)
|
|
27
|
+
ensure # <-- WRONG: ensure must come AFTER rescue
|
|
28
|
+
FileUtils.rm_rf(target)
|
|
29
|
+
rescue StandardError # <-- This causes syntax error
|
|
30
|
+
raise unless TYPES.key?(normalized_extension(archive))
|
|
31
|
+
end
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Fix - swap order so `rescue` comes before `ensure`:
|
|
35
|
+
```ruby
|
|
36
|
+
def extract_and_replace(archive)
|
|
37
|
+
target = Dir.mktmpdir
|
|
38
|
+
extract_recursively(archive, target)
|
|
39
|
+
replace_archive_with_contents(archive, target)
|
|
40
|
+
rescue StandardError
|
|
41
|
+
raise unless TYPES.key?(normalized_extension(archive))
|
|
42
|
+
ensure
|
|
43
|
+
FileUtils.rm_rf(target)
|
|
44
|
+
end
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 2. Run Excavate Tests
|
|
48
|
+
```bash
|
|
49
|
+
cd /Users/mulgogi/src/fontist/excavate
|
|
50
|
+
bundle exec rspec
|
|
51
|
+
```
|
|
52
|
+
All 65 tests should pass.
|
|
53
|
+
|
|
54
|
+
### 3. Bump Excavate Version
|
|
55
|
+
Edit `/Users/mulgogi/src/fontist/excavate/lib/excavate/version.rb`:
|
|
56
|
+
```ruby
|
|
57
|
+
VERSION = "1.0.3"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 4. Commit and Push Excavate
|
|
61
|
+
```bash
|
|
62
|
+
cd /Users/mulgogi/src/fontist/excavate
|
|
63
|
+
git add -A
|
|
64
|
+
git commit -m "fix: prevent memory leaks by ensuring proper resource cleanup
|
|
65
|
+
|
|
66
|
+
- Fix extract_and_replace to use correct rescue/ensure order
|
|
67
|
+
- Add ensure block to extract_by_filter for temp dir cleanup"
|
|
68
|
+
git push origin main
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 5. Release Excavate Gem
|
|
72
|
+
```bash
|
|
73
|
+
cd /Users/mulgogi/src/fontist/excavate
|
|
74
|
+
# Tag and push to rubygems
|
|
75
|
+
git tag v1.0.3
|
|
76
|
+
git push --tags
|
|
77
|
+
gem build excavate.gemspec
|
|
78
|
+
gem push excavate-1.0.3.gem
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 6. Update Fontist to Use New Excavate
|
|
82
|
+
```bash
|
|
83
|
+
cd /Users/mulgogi/src/fontist/fontist
|
|
84
|
+
# Update Gemfile.lock to use excavate >= 1.0.3
|
|
85
|
+
bundle update excavate
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 7. Run Fontist Tests
|
|
89
|
+
```bash
|
|
90
|
+
cd /Users/mulgogi/src/fontist/fontist
|
|
91
|
+
bundle exec rspec
|
|
92
|
+
```
|
|
93
|
+
Tests should pass WITHOUT the `NoMemoryError` at the end.
|
|
94
|
+
|
|
95
|
+
### 8. Create PR and Merge
|
|
96
|
+
- Create PR in fontist repository
|
|
97
|
+
- Reference issue #451
|
|
98
|
+
- Merge after CI passes
|
|
99
|
+
|
|
100
|
+
## Files Modified
|
|
101
|
+
|
|
102
|
+
### Excavate
|
|
103
|
+
- `lib/excavate/archive.rb` - Fix `extract_and_replace` method
|
|
104
|
+
|
|
105
|
+
## Notes
|
|
106
|
+
- Do NOT add `ensure` blocks with `reader&.close` to extractors - the Omnizip readers don't have a `close` method
|
|
107
|
+
- The fix is simple: correct the `rescue`/`ensure` order in `extract_and_replace`
|
data/docs/guide/formulas.md
CHANGED
|
@@ -26,7 +26,7 @@ The main formula repository is [fontist/formulas](https://github.com/fontist/for
|
|
|
26
26
|
- Google Fonts (Roboto, Open Sans, etc.)
|
|
27
27
|
- SIL Fonts
|
|
28
28
|
- macOS system fonts
|
|
29
|
-
- Windows fonts
|
|
29
|
+
- Windows fonts (including Windows Features on Demand)
|
|
30
30
|
- Many other open source fonts
|
|
31
31
|
|
|
32
32
|
### Local Storage
|
|
@@ -257,6 +257,42 @@ fontist create-formula https://dl.winehq.org/wine/source/10.x/wine-10.18.tar.xz
|
|
|
257
257
|
|
|
258
258
|
This generates a formula where all fonts have names prefixed with "Wine ", making it clear these are Wine compatibility fonts rather than the original Microsoft fonts.
|
|
259
259
|
|
|
260
|
+
### Windows Features on Demand (FOD) Formulas
|
|
261
|
+
|
|
262
|
+
Windows FOD formulas use `source: windows_fod` to install fonts via PowerShell's `Add-WindowsCapability`. These formulas don't have download URLs — instead, they specify a Windows capability name:
|
|
263
|
+
|
|
264
|
+
```yaml
|
|
265
|
+
schema_version: 5
|
|
266
|
+
name: Japanese Supplemental Fonts
|
|
267
|
+
platforms:
|
|
268
|
+
- windows
|
|
269
|
+
resources:
|
|
270
|
+
japanese_supplemental_fonts:
|
|
271
|
+
source: windows_fod
|
|
272
|
+
capability_name: "Language.Fonts.Jpan~~~und-JPAN~0.0.1.0"
|
|
273
|
+
fonts:
|
|
274
|
+
- name: Meiryo
|
|
275
|
+
styles:
|
|
276
|
+
- family_name: Meiryo
|
|
277
|
+
type: Regular
|
|
278
|
+
font: Meiryo.ttc
|
|
279
|
+
import_source:
|
|
280
|
+
type: windows
|
|
281
|
+
capability_name: "Language.Fonts.Jpan~~~und-JPAN~0.0.1.0"
|
|
282
|
+
min_windows_version: "10.0"
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Key fields for Windows FOD formulas:
|
|
286
|
+
|
|
287
|
+
| Field | Description |
|
|
288
|
+
|-------|-------------|
|
|
289
|
+
| `resources.*.source` | Must be `windows_fod` |
|
|
290
|
+
| `resources.*.capability_name` | The Windows FOD capability identifier (e.g., `Language.Fonts.Jpan~~~und-JPAN~0.0.1.0`) |
|
|
291
|
+
| `import_source.type` | Must be `windows` |
|
|
292
|
+
| `import_source.min_windows_version` | Minimum Windows version required (default: `10.0`) |
|
|
293
|
+
|
|
294
|
+
These formulas are restricted to the `windows` platform. Attempting to install them on macOS or Linux raises a `PlatformMismatchError`.
|
|
295
|
+
|
|
260
296
|
## Related
|
|
261
297
|
|
|
262
298
|
- [How Fontist Works](/guide/how-it-works) - Internal architecture and indexes
|
data/docs/guide/how-it-works.md
CHANGED
|
@@ -291,6 +291,19 @@ When you run `fontist install "Open Sans"`:
|
|
|
291
291
|
└─────────────────────────────────────────────────────────────┘
|
|
292
292
|
```
|
|
293
293
|
|
|
294
|
+
### Resource Dispatch
|
|
295
|
+
|
|
296
|
+
Fontist selects a download strategy based on the formula's `source` field:
|
|
297
|
+
|
|
298
|
+
| Source | Resource Class | Behavior |
|
|
299
|
+
|--------|---------------|----------|
|
|
300
|
+
| `google` | `GoogleResource` | Downloads from Google Fonts API |
|
|
301
|
+
| `apple_cdn` | `AppleCDNResource` | Downloads from Apple CDN |
|
|
302
|
+
| `windows_fod` | `WindowsFodResource` | Installs via PowerShell `Add-WindowsCapability` |
|
|
303
|
+
| (default) | `ArchiveResource` | Downloads and extracts archive via excavate |
|
|
304
|
+
|
|
305
|
+
For Windows FOD fonts, the flow differs from archives — instead of downloading a file, Fontist checks if the Windows capability is installed and installs it via PowerShell if needed. Font files are then read from `C:\Windows\Fonts`.
|
|
306
|
+
|
|
294
307
|
---
|
|
295
308
|
|
|
296
309
|
## Index Management
|