Skip to content

Instantly share code, notes, and snippets.

@bergwerf
Created February 27, 2017 16:57
Show Gist options
  • Save bergwerf/03cb58804e5627fed2f7a285e421a4f0 to your computer and use it in GitHub Desktop.
Save bergwerf/03cb58804e5627fed2f7a285e421a4f0 to your computer and use it in GitHub Desktop.
HTML template framework prototype
import 'dart:mirrors';
class ElementBuilder {
final String tag;
ElementBuilder(this.tag);
dynamic noSuchMethod(Invocation invocation) {
final pArgs = invocation.positionalArguments;
List<String> classes = [];
List children = [];
var id = '';
var text = '';
// Figure out classes and IDs.
if (pArgs.isNotEmpty) {
// Try to parse first argument as class or ID.
String first = pArgs.first.toString();
final idPattern = new RegExp(r'#([a-z-]+)(?:.|$)');
final classPattern = new RegExp(r'\.([a-z-]+)(?:.|$)');
final idMatch = idPattern.matchAsPrefix(first);
if (idMatch != null) {
id = idMatch.group(1);
first = first.substring(id.length + 1);
}
do {
final classMatch = classPattern.matchAsPrefix(first);
if (classMatch == null) {
id = '';
classes.clear();
text = first;
break;
} else {
classes.add(classMatch.group(1));
first = first.substring(classes.last.length + 1);
}
} while (first.isNotEmpty);
if (text.isEmpty && pArgs.length > 1) {
if (pArgs[1] is List) {
children = pArgs[1];
} else {
text = pArgs[1].toString();
}
}
}
final named = invocation.namedArguments;
final attrs = new Map<String, String>.fromIterable(named.keys,
key: (sym) => MirrorSystem.getName(sym).replaceAll('_', ''),
value: (sym) => named[sym].toString());
if (id.isNotEmpty) {
attrs['id'] = id;
}
if (classes.isNotEmpty) {
attrs['class'] = classes.join(' ');
}
attrs.remove('c');
final akeys = attrs.keys.toList();
final attrsStr = new List<String>.generate(akeys.length,
(i) => '${akeys[i]}="${attrs[akeys[i]]}"').join(' ');
final childrenSymbol = new Symbol('c');
if (named.containsKey(childrenSymbol)) {
children = new List.from(named[childrenSymbol]);
}
// Process children (that is, collapse lists into each other).
var containedLists = true;
while (containedLists) {
containedLists = false;
for (var i = 0; i < children.length; i++) {
if (children[i] is List) {
containedLists = true;
final list = children.removeAt(i);
// Insert all items of this list at this position,
// and move the index forward.
children.insertAll(i, list);
i += list.length - 1;
}
}
}
final open = akeys.isEmpty ? tag : '$tag $attrsStr';
if (children.isNotEmpty) {
return '<$open>${children.join()}</$tag>';
} else if (text.isNotEmpty) {
return '<$open>$text</$tag>';
} else {
return '<$open />';
}
}
}
final div = new ElementBuilder('div');
main() {
print(div('.container', [
[
div('#mydiv.hello', 'Hello World!', stuff: 'a'),
div('#mydiv.hello.hi', 'Hello World!', arst: 'a')
]
])
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment