A framework for building convergent cross-platform Nextcloud clients using Flutter.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.3 KiB

2 years ago
// This script was ported from https://github.com/git-touch/file-icon/blob/master/tool/gulpfile.esm.js and improved in many ways
import 'dart:io';
import 'package:path/path.dart' as p;
final setiUIPath = p.join(
'..',
'..',
'external',
'seti-ui',
);
void main() {
copyFont();
generateData();
}
void copyFont() {
final fontsDir = Directory('fonts');
if (!fontsDir.existsSync()) {
fontsDir.createSync();
}
File(
p.join(
setiUIPath,
'styles',
'_fonts',
'seti',
'seti.ttf',
),
).copySync(p.join('fonts', 'seti.ttf'));
}
void generateData() {
final mappingLess = File(
p.join(
setiUIPath,
'styles',
'components',
'icons',
'mapping.less',
),
).readAsStringSync();
final setiLess = File(
p.join(
setiUIPath,
'styles',
'_fonts',
'seti.less',
),
).readAsStringSync();
final uiVariablesLess = File(
p.join(
setiUIPath,
'styles',
'ui-variables.less',
),
).readAsStringSync();
final colors = <String, String>{'@seti-primary': '_blue'};
final iconSet = <String, List<String>>{};
final codePoints = <String, String>{};
// https://github.com/microsoft/vscode/blob/554182620f43390075d8c7e7fa36634288ef4e2d/extensions/theme-seti/build/update-icon-theme.js#L345
for (final match
in RegExp('\\.icon-(?:set|partial)\\([\'"]([\\w-.+]+)[\'"],\\s*[\'"]([\\w-]+)[\'"],\\s*(@[\\w-]+)\\)')
.allMatches(mappingLess)) {
final pattern = match.group(1)!.toLowerCase();
final type = match.group(2)!;
final colorName = match.group(3)!;
if (colorName != '@seti-primary') {
colors[colorName] = '';
}
if (iconSet[pattern] == null) {
iconSet[pattern] = [type, colorName];
}
}
for (final match in RegExp("^\t@([a-zA-Z0-9-_]+): '\\\\([A-Z0-9]+)';\$", multiLine: true).allMatches(setiLess)) {
codePoints[match.group(1)!] = '0x${match.group(2)!}';
}
for (final match
in RegExp('^(${colors.keys.join('|')}): #([a-f0-9]+);\$', multiLine: true).allMatches(uiVariablesLess)) {
final colorName = match.group(1)!;
final hexCode = match.group(2)!;
assert(hexCode.length == 6, 'CSS hex color needs to be six characters long');
colors[colorName] = '0xff$hexCode';
}
final code = <String>[
'// THIS CODE IS GENERATED - DO NOT EDIT MANUALLY',
'',
"import 'package:file_icons/src/meta.dart';",
'',
'// Code points',
// This filters unused codepoints.
for (final type in codePoints.keys
.where((final type) => iconSet.keys.map((final pattern) => iconSet[pattern]![0] == type).contains(true))) ...[
'const ${_toVariableName(type)} = ${codePoints[type]};',
],
'',
'// Colors',
for (final colorName in colors.keys) ...[
'const ${_toVariableName(colorName)} = ${colors[colorName]};',
],
'',
'/// Mapping between file extensions and code points and colors',
'const iconSetMap = {',
// This filters icons where the code points are missing. That indicates the fonts in seti-ui are not up-to-date.
// Run `gulp icons` in the seti-ui repository and everything should be there.
// Please submit the changes upstream if you can.
for (final pattern in iconSet.keys.where((final pattern) => codePoints.keys.contains(iconSet[pattern]![0]))) ...[
" '$pattern': SetiMeta(${_toVariableName(iconSet[pattern]![0])}, ${_toVariableName(iconSet[pattern]![1])}),",
],
'};',
'',
];
final missingCodePoints = iconSet.keys.where((final pattern) => !codePoints.keys.contains(iconSet[pattern]![0]));
if (missingCodePoints.isNotEmpty) {
print(
'WARNING: Missing code points for ${missingCodePoints.map((final pattern) => iconSet[pattern]![0]).toSet().join(', ')}',
);
}
File(
p.join(
'lib',
'src',
'data.dart',
),
).writeAsStringSync(code.join('\n'));
}
String _toVariableName(final String key) {
final result = StringBuffer('_');
final parts = key.split('');
for (var i = 0; i < parts.length; i++) {
var char = parts[i];
final prevChar = i > 0 ? parts[i - 1] : null;
if (char == '@' || char == '-' || char == '_') {
continue;
}
if (prevChar == '-' || prevChar == '_') {
char = char.toUpperCase();
}
if (i == 0) {
char = char.toLowerCase();
}
result.write(char);
}
return result.toString();
}