$ErrorActionPreference = 'Stop' $ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" $fontsDir = Join-Path $PSScriptRoot "..\data\fonts" $fontsDir = (Resolve-Path $fontsDir).Path $families = @( @{ name = 'Inter'; query = 'Inter' }, @{ name = 'Lora'; query = 'Lora' }, @{ name = 'Merriweather'; query = 'Merriweather' }, @{ name = 'OpenSans'; query = 'Open+Sans' }, @{ name = 'PlayfairDisplay'; query = 'Playfair+Display' }, @{ name = 'Roboto'; query = 'Roboto' }, @{ name = 'WorkSans'; query = 'Work+Sans' } ) foreach ($f in $families) { $cssUrl = "https://fonts.googleapis.com/css2?family=$($f.query):ital,wght@0,400;0,700;1,400;1,700&display=swap" Write-Host "=== $($f.name) ===" -ForegroundColor Cyan Write-Host "CSS: $cssUrl" $css = (Invoke-WebRequest -Uri $cssUrl -UserAgent $ua -UseBasicParsing).Content $pattern = '/\*\s*latin\s*\*/\s*@font-face\s*\{([^}]+)\}' $matches = [regex]::Matches($css, $pattern) Write-Host "Found $($matches.Count) latin @font-face blocks" foreach ($m in $matches) { $block = $m.Groups[1].Value $weight = [regex]::Match($block, 'font-weight:\s*(\d+)').Groups[1].Value $style = [regex]::Match($block, 'font-style:\s*(\w+)').Groups[1].Value $url = [regex]::Match($block, 'url\(([^)]+\.woff2)\)').Groups[1].Value if (-not $url) { Write-Host " skip block: no woff2 url"; continue } $suffix = '' if ($style -eq 'italic' -and $weight -eq '700') { $suffix = '-BoldItalic' } elseif ($style -eq 'italic') { $suffix = '-Italic' } elseif ($weight -eq '700') { $suffix = '-Bold' } $outFile = Join-Path $fontsDir "$($f.name)$suffix.woff2" Invoke-WebRequest -Uri $url -OutFile $outFile -UserAgent $ua -UseBasicParsing $size = (Get-Item $outFile).Length Write-Host (" -> {0} ({1} bytes)" -f (Split-Path $outFile -Leaf), $size) } } Write-Host "`nDone." -ForegroundColor Green Write-Host "Files in ${fontsDir}:" Get-ChildItem $fontsDir -Filter '*.woff2' | Sort-Object Name | ForEach-Object { Write-Host (" {0,-30} {1,8} bytes" -f $_.Name, $_.Length) }