| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Regenerates the material icons file. |
| // See https://github.com/flutter/flutter/wiki/Updating-Material-Design-Fonts |
| |
| import 'dart:convert' show LineSplitter; |
| import 'dart:io'; |
| |
| import 'package:args/args.dart'; |
| import 'package:path/path.dart' as path; |
| |
| const String kOptionCodepointsPath = 'codepoints'; |
| const String kOptionIconsPath = 'icons'; |
| const String kOptionDryRun = 'dry-run'; |
| |
| const String kDefaultCodepointsPath = 'bin/cache/artifacts/material_fonts/codepoints'; |
| const String kDefaultIconsPath = 'packages/flutter/lib/src/material/icons.dart'; |
| |
| const String kBeginGeneratedMark = '// BEGIN GENERATED'; |
| const String kEndGeneratedMark = '// END GENERATED'; |
| |
| const Map<String, String> kIdentifierRewrites = const <String, String>{ |
| '360': 'threesixty', |
| '3d_rotation': 'threed_rotation', |
| '4k': 'four_k', |
| 'class': 'class_', |
| }; |
| |
| void main(List<String> args) { |
| // If we're run from the `tools` dir, set the cwd to the repo root. |
| if (path.basename(Directory.current.path) == 'tools') |
| Directory.current = Directory.current.parent.parent; |
| |
| ArgParser argParser = new ArgParser(); |
| argParser.addOption(kOptionCodepointsPath, defaultsTo: kDefaultCodepointsPath); |
| argParser.addOption(kOptionIconsPath, defaultsTo: kDefaultIconsPath); |
| argParser.addFlag(kOptionDryRun, defaultsTo: false); |
| ArgResults argResults = argParser.parse(args); |
| |
| File iconFile = new File(path.absolute(argResults[kOptionIconsPath])); |
| if (!iconFile.existsSync()) { |
| stderr.writeln('Icons file not found: ${iconFile.path}'); |
| exit(1); |
| } |
| File codepointsFile = new File(path.absolute(argResults[kOptionCodepointsPath])); |
| if (!codepointsFile.existsSync()) { |
| stderr.writeln('Codepoints file not found: ${codepointsFile.path}'); |
| exit(1); |
| } |
| |
| String iconData = iconFile.readAsStringSync(); |
| String codepointData = codepointsFile.readAsStringSync(); |
| String newIconData = regenerateIconsFile(iconData, codepointData); |
| |
| if (argResults[kOptionDryRun]) |
| stdout.writeln(newIconData); |
| else |
| iconFile.writeAsStringSync(newIconData); |
| } |
| |
| String regenerateIconsFile(String iconData, String codepointData) { |
| StringBuffer buf = new StringBuffer(); |
| bool generating = false; |
| for (String line in LineSplitter.split(iconData)) { |
| if (!generating) |
| buf.writeln(line); |
| if (line.contains(kBeginGeneratedMark)) { |
| generating = true; |
| String iconDeclarations = generateIconDeclarations(codepointData); |
| buf.write(iconDeclarations); |
| } else if (line.contains(kEndGeneratedMark)) { |
| generating = false; |
| buf.writeln(line); |
| } |
| } |
| return buf.toString(); |
| } |
| |
| String generateIconDeclarations(String codepointData) { |
| return LineSplitter.split(codepointData) |
| .map((String l) => l.trim()) |
| .where((String l) => l.isNotEmpty) |
| .map(getIconDeclaration) |
| .join(); |
| } |
| |
| String getIconDeclaration(String line) { |
| List<String> tokens = line.split(' '); |
| if (tokens.length != 2) |
| throw new FormatException('Unexpected codepoint data: $line'); |
| String name = tokens[0]; |
| String codepoint = tokens[1]; |
| String identifier = kIdentifierRewrites[name] ?? name; |
| String description = name.replaceAll('_', ' '); |
| return ''' |
| |
| /// <p><i class="material-icons md-36">$name</i> — material icon named "$description".</p> |
| static const IconData $identifier = const IconData(0x$codepoint); |
| '''; |
| } |