icons.rake 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. # frozen_string_literal: true
  2. def download_material_icon(icon, weight: 400, filled: false, size: 20)
  3. url_template = Addressable::Template.new('https://fonts.gstatic.com/s/i/short-term/release/materialsymbolsoutlined/{icon}/{axes}/{size}px.svg')
  4. variant = filled ? '-fill' : ''
  5. axes = []
  6. axes << "wght#{weight}" if weight != 400
  7. axes << 'fill1' if filled
  8. axes = axes.join.presence || 'default'
  9. url = url_template.expand(icon: icon, axes: axes, size: size).to_s
  10. path = Rails.root.join('app', 'javascript', 'material-icons', "#{weight}-#{size}px", "#{icon}#{variant}.svg")
  11. FileUtils.mkdir_p(File.dirname(path))
  12. File.write(path, HTTP.get(url).to_s)
  13. end
  14. def find_used_icons
  15. icons_by_weight_and_size = {}
  16. Rails.root.glob('app/javascript/**/*.*s*').map do |path|
  17. File.open(path, 'r') do |file|
  18. pattern = %r{\Aimport .* from '@/material-icons/(?<weight>[0-9]+)-(?<size>[0-9]+)px/(?<icon>[^-]*)(?<fill>-fill)?.svg\?react';}
  19. file.each_line do |line|
  20. match = pattern.match(line)
  21. next if match.blank?
  22. weight = match['weight'].to_i
  23. size = match['size'].to_i
  24. icons_by_weight_and_size[weight] ||= {}
  25. icons_by_weight_and_size[weight][size] ||= Set.new
  26. icons_by_weight_and_size[weight][size] << match['icon']
  27. end
  28. end
  29. end
  30. Rails.root.join('config', 'navigation.rb').open('r') do |file|
  31. pattern = /material_symbol\('(?<icon>[^']*)'\)/
  32. file.each_line do |line|
  33. match = pattern.match(line)
  34. next if match.blank?
  35. # navigation.rb only uses 400x24 icons, per material_symbol() in
  36. # app/helpers/application_helper.rb
  37. icons_by_weight_and_size[400] ||= {}
  38. icons_by_weight_and_size[400][24] ||= Set.new
  39. icons_by_weight_and_size[400][24] << match['icon']
  40. end
  41. end
  42. icons_by_weight_and_size
  43. end
  44. namespace :icons do
  45. desc 'Download used Material Symbols icons'
  46. task download: :environment do
  47. find_used_icons.each do |weight, icons_by_size|
  48. icons_by_size.each do |size, icons|
  49. icons.each do |icon|
  50. download_material_icon(icon, weight: weight, size: size)
  51. download_material_icon(icon, weight: weight, size: size, filled: true)
  52. end
  53. end
  54. end
  55. end
  56. end