build method
Main method to generate the output file.
Implementation
@override
Future<void> build(BuildStep buildStep) async {
/// Reading the configuration from build.yaml
final config = options.config;
/// Path to the fonts directory
final fontPath = config['font_path'] as String? ?? 'assets/fonts/';
/// Output directory for the generated file
final outputDir = config['output_dir'] as String? ?? 'lib/generated';
/// Minimum font size to generate
final min = config['min'] as int? ?? 8;
/// Maximum font size to generate
final max = config['max'] as int? ?? 64;
/// Default text color to use
final defaultColorSetting =
config['default_palette'] as String? ?? defaultColor;
/// Name of the generated class (new functionality)
final className = config['class_name'] as String? ?? 'TextStyles';
/// Output file ID for the generated text styles
final outputId = AssetId(
buildStep.inputId.package,
'$outputDir/text_styles.g.dart',
);
final fontsDir = Directory(fontPath);
/// Check if the fonts directory exists
if (!fontsDir.existsSync()) {
await buildStep.writeAsString(outputId,
_emptyGeneratedFile('Fonts directory "$fontPath" does not exist.'));
log.severe(
'[textstyle_generator] Fonts directory "$fontPath" does not exist.');
return;
}
/// List of all .ttf and .otf font files
final fontFiles = fontsDir
.listSync(recursive: true)
.whereType<File>()
.where((f) => f.path.endsWith('.ttf') || f.path.endsWith('.otf'))
.toList();
/// Check if any fonts were found
if (fontFiles.isEmpty) {
await buildStep.writeAsString(
outputId, _emptyGeneratedFile('No font files found at "$fontPath".'));
log.severe('[textstyle_generator] No font files found in "$fontPath".');
return;
}
/// Buffer for writing the Dart output file
final buffer = StringBuffer();
/// Set of already generated method names to avoid duplicates
final generatedMethodNames = <String>{};
/// Writing the file header
buffer.writeln('// GENERATED CODE - DO NOT MODIFY BY HAND');
buffer.writeln('// *****************************************************');
buffer.writeln('// textstyle_generator');
buffer
.writeln('// *****************************************************\n');
buffer.writeln("part of '../textstyle_generator_trigger.dart';\n");
/// Start of the configurable class (default: TextStyles)
buffer.writeln('class $className {');
buffer.writeln(' const $className._();\n');
/// Iterate over all font files
for (var i = 0; i < fontFiles.length; i++) {
final fontFile = fontFiles[i];
final name = fontFile.uri.pathSegments.last.split('.').first;
final familyParts = name.split('-');
final baseFamily = familyParts.take(familyParts.length - 1).join('-');
final styleDescriptor =
familyParts.length > 1 ? familyParts.last : 'Regular';
final fontLower = _normalizeFamilyName(baseFamily);
final parsed = _parseFontDescriptor(styleDescriptor);
/// Generate methods for each font size
for (var size = min; size <= max; size++) {
final methodName = '$fontLower${size}w${parsed.weight}${parsed.suffix}';
if (generatedMethodNames.contains(methodName)) {
continue;
}
generatedMethodNames.add(methodName);
final fontFullName = name;
/// Write a method for a specific text style
buffer.writeln(
' static TextStyle $methodName({Color? c, double? h, double? l}) => TextStyle(');
buffer.writeln(" fontFamily: '$fontFullName',");
buffer.writeln(' fontSize: $size,');
buffer.writeln(' fontWeight: FontWeight.w${parsed.weight},');
buffer.writeln(' color: c ?? $defaultColorSetting,');
buffer.writeln(' height: h,');
buffer.writeln(' letterSpacing: l,');
buffer.writeln(' );\n');
}
}
/// End of the configurable class
buffer.writeln('}');
/// Save the final output file
await buildStep.writeAsString(outputId, buffer.toString());
log.info(
'[textstyle_generator] Successfully generated: $outputDir/text_styles.g.dart');
}