Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
lukas-h committed Sep 5, 2022
1 parent 64f8a89 commit 37883ea
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 232 deletions.
5 changes: 4 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
# Defines a default set of lint rules enforced for
# projects at Google. For details and rationale,
# see https://github.com/dart-lang/pedantic#enabled-lints.
include: package:pedantic/analysis_options.yaml
include: package:lints/recommended.yaml

# For lint rules and documentation, see http://dart-lang.github.io/linter/lints.
# Uncomment to specify additional rules.
# linter:
# rules:
# - camel_case_types

linter:
rules:
prefer_function_declarations_over_variables: false
analyzer:
# exclude:
# - path/to/excluded/files/**
4 changes: 2 additions & 2 deletions lib/src/buildin_tags/for.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ class For extends Block {
@override
String toString() {
var innerC = innerChildren.toString();
if (innerC.length > 40) innerC = innerC.substring(0, 30) + '...' + innerC.substring(innerC.length - 7);
if (innerC.length > 40) innerC = '${innerC.substring(0, 30)}...${innerC.substring(innerC.length - 7)}';
var elseC = elseChildren.toString();
if (elseC.length > 40) elseC = elseC.substring(0, 30) + '...' + elseC.substring(elseC.length - 7);
if (elseC.length > 40) elseC = '${elseC.substring(0, 30)}...${elseC.substring(elseC.length - 7)}';
return 'For{from: $from, to: $to, innerChildren: $innerC, elseChildren: $elseC}';
}
}
Expand Down
13 changes: 4 additions & 9 deletions lib/src/buildin_tags/regroup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ class Regroup extends Block {
List list = await from.evaluate(context);
var collection = List.from(list);
var groupers = <String>{};
collection.forEach((element) {
for (var element in collection) {
groupers.add(element[groupBy]);
});
}

var result = [];
groupers.forEach((grouper) {
for (var grouper in groupers) {
var item = {};
item['grouper'] = grouper;
item['list'] = collection.where((element) => element[groupBy] == grouper).toList();
result.add(item);
});
}
context.variables[to] = result;
}

Expand All @@ -42,11 +42,6 @@ class Regroup extends Block {
}

class _RegroupBlockParser extends BlockParser {
@override
void start(context, args) {
super.start(context, args);
}

// {% for athlete in athlete_list %}
// {% regroup cities by country as country_list %}
@override
Expand Down
156 changes: 47 additions & 109 deletions lib/src/builtins.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,28 +72,19 @@ class BuiltinsModule implements Module {

context.filters['downcase'] = context.filters['lower'] = (input, args) => input!.toString().toLowerCase();

context.filters['upcase'] = context.filters['upper'] =
(input, args) => input?.toString()?.toUpperCase();
context.filters['upcase'] = context.filters['upper'] = (input, args) => input?.toString().toUpperCase();

context.filters['capitalize'] = context.filters['capfirst'] = (input, args) => input!.toString().replaceFirstMapped(
RegExp(r'^\w'),
(m) => m.group(0)!.toUpperCase(),
);

context.filters['join'] = (input, args) => (input as Iterable)
.join(args != null && args.isNotEmpty ? args[0] : ' ');
context.filters['abs'] =
(input, args) => input is num ? input.abs() : num.tryParse(input).abs();
context.filters['append'] = (input, args) =>
args != null && args.isNotEmpty && input is String
? input + args[0]
: input;
context.filters['at_least'] = (input, args) =>
args != null && args.isNotEmpty && input < args[0] ? args[0] : input;
context.filters['at_most'] = (input, args) =>
args != null && args.isNotEmpty && input > args[0] ? args[0] : input;
context.filters['ceil'] = (input, args) =>
input is num ? input.ceil() : num.tryParse(input).ceil();
context.filters['join'] = (input, args) => (input as Iterable).join(args.isNotEmpty ? args[0] : ' ');
context.filters['abs'] = (input, args) => input is num ? input.abs() : num.tryParse(input)?.abs();
context.filters['append'] = (input, args) => args.isNotEmpty && input is String ? input + args[0] : input;
context.filters['at_least'] = (input, args) => args.isNotEmpty && input < args[0] ? args[0] : input;
context.filters['at_most'] = (input, args) => args.isNotEmpty && input > args[0] ? args[0] : input;
context.filters['ceil'] = (input, args) => input is num ? input.ceil() : num.tryParse(input)?.ceil();
context.filters['compact'] = (input, args) {
var out = input;
if (out is List) {
Expand All @@ -103,7 +94,7 @@ class BuiltinsModule implements Module {
};
context.filters['concat'] = (input, args) {
var out = input;
if (out is List && args != null && args.isNotEmpty) {
if (out is List && args.isNotEmpty) {
for (var arg in args) {
out.add(arg);
}
Expand All @@ -112,26 +103,17 @@ class BuiltinsModule implements Module {
};

// (ruby-style)
context.filters['date'] = (input, args) => args != null && args.length == 1
? strptime(input as DateTime, args[0])
: strptime(input as DateTime, '%c');
context.filters['date'] = (input, args) => args.length == 1 ? strptime(input as DateTime, args[0]) : strptime(input as DateTime, '%c');

// (dart-style)
context.filters['date_format'] = (input, args) =>
DateFormat(args != null && args.isNotEmpty ? args[0] : 'yMMMMd')
.format(input as DateTime);
context.filters['divided_by'] = (input, args) =>
args != null && args.isNotEmpty
? (input as num) / (args[0] as num)
: input;
context.filters['date_format'] = (input, args) => DateFormat(args.isNotEmpty ? args[0] : 'yMMMMd').format(input as DateTime);
context.filters['divided_by'] = (input, args) => args.isNotEmpty ? (input as num) / (args[0] as num) : input;
context.filters['first'] = (input, args) => (input as List).first;
context.filters['last'] = (input, args) => (input as List).last;
context.filters['floor'] = (input, args) =>
input is num ? input.floor() : num.tryParse(input).floor();
context.filters['lstrip'] = context.filters['trim_left'] =
(input, args) => input.toString().trimLeft();
context.filters['floor'] = (input, args) => input is num ? input.floor() : num.tryParse(input)?.floor();
context.filters['lstrip'] = context.filters['trim_left'] = (input, args) => input.toString().trimLeft();
context.filters['map'] = (input, args) {
if (args != null && args.length == 1) {
if (args.length == 1) {
var key = args[0];
if (input is List) {
return input.map((m) => (m as Map)[key]);
Expand All @@ -141,57 +123,32 @@ class BuiltinsModule implements Module {
}
return input;
};
context.filters['minus'] = (input, args) => args != null && args.isNotEmpty
? (input as num) - (args[0] as num)
: input;
context.filters['modulo'] = (input, args) => args != null && args.isNotEmpty
? (input as num) % (args[0] as num)
: input;
context.filters['newline_to_br'] =
(input, args) => input.toString().replaceAll('\n', '<br />');
context.filters['plus'] = (input, args) => args != null && args.isNotEmpty
? (input as num) + (args[0] as num)
: input;
context.filters['prepend'] = (input, args) =>
args != null && args.isNotEmpty ? args[0] + input : input;
context.filters['remove'] = (input, args) => args != null && args.isNotEmpty
? input.toString().replaceAll(args[0], '')
: input;
context.filters['remove_first'] = (input, args) =>
args != null && args.isNotEmpty
? input.toString().replaceFirst(args[0], '')
: input;
context.filters['replace'] = (input, args) =>
args != null && args.length == 2
? input.toString().replaceAll(args[0], args[1])
: input;

context.filters['replace_first'] = (input, args) =>
args != null && args.length > 1
? input
.toString()
.replaceFirst(args[0], args[1], args.length == 3 ? args[2] : 0)
: input;
context.filters['minus'] = (input, args) => args.isNotEmpty ? (input as num) - (args[0] as num) : input;
context.filters['modulo'] = (input, args) => args.isNotEmpty ? (input as num) % (args[0] as num) : input;
context.filters['newline_to_br'] = (input, args) => input.toString().replaceAll('\n', '<br />');
context.filters['plus'] = (input, args) => args.isNotEmpty ? (input as num) + (args[0] as num) : input;
context.filters['prepend'] = (input, args) => args.isNotEmpty ? args[0] + input : input;
context.filters['remove'] = (input, args) => args.isNotEmpty ? input.toString().replaceAll(args[0], '') : input;
context.filters['remove_first'] = (input, args) => args.isNotEmpty ? input.toString().replaceFirst(args[0], '') : input;
context.filters['replace'] = (input, args) => args.length == 2 ? input.toString().replaceAll(args[0], args[1]) : input;

context.filters['replace_first'] = (input, args) => args.length > 1 ? input.toString().replaceFirst(args[0], args[1], args.length == 3 ? args[2] : 0) : input;
context.filters['reverse'] = (input, args) => (input as List).reversed;
context.filters['round'] = (input, args) =>
input is num ? input.round() : num.tryParse(input).round();
context.filters['rstrip'] = context.filters['trim_right'] =
(input, args) => input.toString().trimRight();
context.filters['round'] = (input, args) => input is num ? input.round() : num.tryParse(input)?.round();
context.filters['rstrip'] = context.filters['trim_right'] = (input, args) => input.toString().trimRight();
context.filters['slice'] = (input, args) {
if (args != null) {
switch (args.length) {
case 1:
return input.toString()[args[0]];
case 2:
return input.toString().substring(args[0], args[1]);
}
} else {
return input;
switch (args.length) {
case 1:
return input.toString()[args[0]];
case 2:
return input.toString().substring(args[0], args[1]);
default:
return input;
}
};
context.filters['sort'] = (input, args) {
var out = input;
if (input is List && args != null && args.length == 1) {
if (input is List && args.length == 1) {
var key = args[0];
out.sort((a, b) => a[key].toString().compareTo(b[key].toString()));
} else if (input is List) {
Expand All @@ -201,58 +158,39 @@ class BuiltinsModule implements Module {
};
context.filters['sort_natural'] = (input, args) {
var out = input;
if (input is List && args != null && args.length == 1) {
if (input is List && args.length == 1) {
var key = args[0];
out.sort((a, b) => a[key]
.toString()
.toLowerCase()
.compareTo(b[key].toString().toLowerCase()));
out.sort((a, b) => a[key].toString().toLowerCase().compareTo(b[key].toString().toLowerCase()));
} else if (input is List) {
out.sort((a, b) =>
a.toString().toLowerCase().compareTo(b.toString().toLowerCase()));
out.sort((a, b) => a.toString().toLowerCase().compareTo(b.toString().toLowerCase()));
}
return out;
};
context.filters['split'] = (input, args) => args != null && args.isNotEmpty
? input.toString().split(args[0])
: input;
context.filters['strip'] =
context.filters['trim'] = (input, args) => input.toString().trim();
context.filters['strip_html'] = (input, args) => input
.toString()
.replaceAll(
RegExp(r'<[^>]*>', multiLine: true, caseSensitive: true), '');
context.filters['strip_newlines'] =
(input, args) => input.toString().replaceAll('\n', '');
context.filters['times'] = (input, args) => args != null && args.isNotEmpty
? (input as num) * (args[0] as num)
: input;
context.filters['truncate'] = (input, args) =>
args != null && args.isNotEmpty && input.length > args[0]
? input.substring(0, args[0] - 3) + '...'
: input;
context.filters['split'] = (input, args) => args.isNotEmpty ? input.toString().split(args[0]) : input;
context.filters['strip'] = context.filters['trim'] = (input, args) => input.toString().trim();
context.filters['strip_html'] = (input, args) => input.toString().replaceAll(RegExp(r'<[^>]*>', multiLine: true, caseSensitive: true), '');
context.filters['strip_newlines'] = (input, args) => input.toString().replaceAll('\n', '');
context.filters['times'] = (input, args) => args.isNotEmpty ? (input as num) * (args[0] as num) : input;
context.filters['truncate'] = (input, args) => args.isNotEmpty && input.length > args[0] ? input.substring(0, args[0] - 3) + '...' : input;
context.filters['truncatewords'] = (input, args) {
if (args != null && args.isNotEmpty) {
if (args.isNotEmpty) {
switch (args.length) {
case 1:
return input.toString().split(' ').sublist(0, args[0]).join(' ');
case 2:
return input.toString().split(' ').sublist(0, args[0]).join(' ') +
args[1];
return input.toString().split(' ').sublist(0, args[0]).join(' ') + args[1];
}
} else {
return input;
}
};
context.filters['uniq'] =
(input, args) => input is List ? input.toSet() : input;
context.filters['uniq'] = (input, args) => input is List ? input.toSet() : input;
context.filters['url_decode'] = (input, args) => Uri.decodeFull(input);
context.filters['url_encode'] = (input, args) => Uri.encodeFull(input);
context.filters['escape'] = (input, args) => Uri.encodeComponent(
input.toString(),
);
// TODO context.filters['escape_once']
context.filters['to_base64'] = context.filters['image_to_base64'] =
(input, args) => base64Encode(input as List<int>);
context.filters['to_base64'] = context.filters['image_to_base64'] = (input, args) => base64Encode(input as List<int>);
}
}
2 changes: 1 addition & 1 deletion lib/src/context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class Context implements RenderContext, ParseContext {
@override
RenderContext get root => parent == null ? this : parent!.root;

Context._({Context? parent}) : parent = parent;
Context._({this.parent});

@override
void registerModule(String load) {
Expand Down
2 changes: 2 additions & 0 deletions lib/src/model.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ignore_for_file: constant_identifier_names

export 'model_web.dart' if (dart.library.io) 'model_io.dart';

abstract class Root {
Expand Down
42 changes: 21 additions & 21 deletions lib/src/parser/lexer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import 'package:string_scanner/string_scanner.dart';

import '../model.dart';

class _TokenCreator {
class TokenCreator {
final TokenType type;
final RegExp pattern;

_TokenCreator(this.type, String pattern) : pattern = RegExp(pattern, dotAll: true);
TokenCreator(this.type, String pattern) : pattern = RegExp(pattern, dotAll: true);

Token? scan(Source source, LineScanner ss) {
final line = ss.line;
Expand All @@ -19,26 +19,26 @@ class _TokenCreator {
}

class Lexer {
final List<_TokenCreator> tokenCreators = [
_TokenCreator(TokenType.comparison, r'==|!=|<>|<=?|>=?'),
_TokenCreator(TokenType.single_string, r"'[^\']*'"),
_TokenCreator(TokenType.double_string, r'"[^\"]*"'),
_TokenCreator(TokenType.number, r'-?\d+(\.\d+)?'),
_TokenCreator(TokenType.identifier, r'[a-zA-Z_][\w-]*\??'),
_TokenCreator(TokenType.dotdot, r'\.\.'),
_TokenCreator(TokenType.pipe, r'\|'),
_TokenCreator(TokenType.dot, r'\.'),
_TokenCreator(TokenType.assign, '='),
_TokenCreator(TokenType.colon, ':'),
_TokenCreator(TokenType.comma, ','),
_TokenCreator(TokenType.open_square, r'\['),
_TokenCreator(TokenType.close_square, ']'),
_TokenCreator(TokenType.open_banana, r'\('),
_TokenCreator(TokenType.close_banana, r'\)'),
_TokenCreator(TokenType.question, r'\?'),
_TokenCreator(TokenType.dash, '-'),
final List<TokenCreator> tokenCreators = [
TokenCreator(TokenType.comparison, r'==|!=|<>|<=?|>=?'),
TokenCreator(TokenType.single_string, r"'[^\']*'"),
TokenCreator(TokenType.double_string, r'"[^\"]*"'),
TokenCreator(TokenType.number, r'-?\d+(\.\d+)?'),
TokenCreator(TokenType.identifier, r'[a-zA-Z_][\w-]*\??'),
TokenCreator(TokenType.dotdot, r'\.\.'),
TokenCreator(TokenType.pipe, r'\|'),
TokenCreator(TokenType.dot, r'\.'),
TokenCreator(TokenType.assign, '='),
TokenCreator(TokenType.colon, ':'),
TokenCreator(TokenType.comma, ','),
TokenCreator(TokenType.open_square, r'\['),
TokenCreator(TokenType.close_square, ']'),
TokenCreator(TokenType.open_banana, r'\('),
TokenCreator(TokenType.close_banana, r'\)'),
TokenCreator(TokenType.question, r'\?'),
TokenCreator(TokenType.dash, '-'),
];
final markup = _TokenCreator(TokenType.markup, r'((?!{{)(?!{%)(?![\s\n\r]*{[{%]-).)+');
final markup = TokenCreator(TokenType.markup, r'((?!{{)(?!{%)(?![\s\n\r]*{[{%]-).)+');
final whitespace = RegExp(r'\s*');

Iterable<Token> tokenize(Source source) sync* {
Expand Down
3 changes: 2 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ environment:
dependencies:
string_scanner: ^1.1.0
intl: ^0.17.0



dev_dependencies:
pedantic: ^1.11.0
lints: ^2.0.0
test: ^1.17.7
Loading

0 comments on commit 37883ea

Please sign in to comment.