Skip to content

Instantly share code, notes, and snippets.

@rodydavis
Last active May 29, 2024 21:21
Show Gist options
  • Save rodydavis/53d371e9e15147fe54dcf349bdc3452d to your computer and use it in GitHub Desktop.
Save rodydavis/53d371e9e15147fe54dcf349bdc3452d to your computer and use it in GitHub Desktop.
Example of a possible Dart DSX (JSX like syntax) inspired by Templ in Go lang
import 'dart:io';
void main() {
final file = File('lib/hello.dsx');
final out = File('lib/hello.g.dart');
out.createSync();
out.writeAsStringSync(convert(file.readAsStringSync()));
}
String convert(String raw) {
final result = StringBuffer();
final lines = raw.split('\n');
var isAsync = false;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.trimLeft().startsWith('template ')) {
isAsync = false;
if (line.contains(') async {')) {
isAsync = true;
line = line.replaceFirst('template ', 'Stream<String> ');
line = line.replaceAll(') async {', ') async* {');
} else {
line = line.replaceFirst('template ', 'Iterable<String> ');
line = line.replaceAll(') {', ') sync* {');
}
result.writeln(line);
continue;
} else if (line.trimLeft().startsWith('<')) {
// Convert to string replace
result.write(" yield '");
result.write(line.trimLeft());
result.writeln("';");
void addRawTag(String tag) {
if (line.trimLeft().startsWith('<$tag')) {
line = lines[++i];
while (!line.trimLeft().startsWith('</$tag')) {
result.write(' yield "');
result.write(line.replaceFirst(' ', ''));
result.writeln('";');
line = lines[++i];
}
result.write(" yield '");
result.write(line.trimLeft());
result.writeln("';");
}
}
const tags = ['style', 'script'];
for (final tag in tags) {
addRawTag(tag);
}
continue;
} else if (line.trimLeft().startsWith('@')) {
// Convert to string replace
result.write(' yield* ');
if (isAsync) {
result.write(' Stream.fromIterable(');
}
result.write(line.replaceFirst(' ', '').replaceFirst('@', ''));
if (isAsync) {
result.write(' )');
}
result.writeln(';');
continue;
}
result.writeln(line);
}
return result.toString();
}
template Hello(String name, {bool active = false}) {
<div>Hello, ${name}!</div>
if (active) {
<div class="badge">You are awesome!</div>
}
}
template Base(String title) async {
<html>
<head>
<title>${title}</title>
<style>
body {
font-family: 'Roboto';
}
</style>
</head>
<body>
@Hello('World', active: true)
</body>
</html>
}
template RemoteData(String path) async {
final response = await Future.value(0);
<div>Result: $response</div>
}
template Counter(int id, [int count = 0]) {
<h2>Counter: $id</h2>
<button id="counter-$id" data-count="$count">Count: $count</button>
<script>
const counter_$id = document.querySelector(`#counter-$id`);
counter_$id.addEventListener('click', inc, false);
function inc() {
let count = parseInt(counter_$id.getAttribute('data-count'));
count += 1;
counter_$id.innerHTML = `Count: \${count}`;
counter_$id.setAttribute('data-count', count);
}
</script>
}
template Counters(int count) {
<h1>Counters</h1>
for (var i = 0; i < count; i++) {
@Counter(i);
}
}
Iterable<String> Hello(String name, {bool active = false}) sync* {
yield '<div>Hello, ${name}!</div>';
if (active) {
yield '<div class="badge">You are awesome!</div>';
}
}
Stream<String> Base(String title) async* {
yield '<html>';
yield '<head>';
yield '<title>${title}</title>';
yield '<style>';
yield " body {";
yield " font-family: 'Roboto';";
yield " }";
yield '</style>';
yield '</head>';
yield '<body>';
yield* Stream.fromIterable( Hello('World', active: true) );
yield '</body>';
yield '</html>';
}
Stream<String> RemoteData(String path) async* {
final response = await Future.value(0);
yield '<div>Result: $response</div>';
}
Iterable<String> Counter(int id, [int count = 0]) sync* {
yield '<h2>Counter: $id</h2>';
yield '<button id="counter-$id" data-count="$count">Count: $count</button>';
yield '<script>';
yield " const counter_$id = document.querySelector(`#counter-$id`);";
yield " counter_$id.addEventListener('click', inc, false);";
yield "";
yield " function inc() {";
yield "let count = parseInt(counter_$id.getAttribute('data-count'));";
yield "count += 1;";
yield "counter_$id.innerHTML = `Count: \${count}`;";
yield "counter_$id.setAttribute('data-count', count);";
yield " }";
yield '</script>';
}
Iterable<String> Counters(int count) sync* {
yield '<h1>Counters</h1>';
for (var i = 0; i < count; i++) {
yield* Counter(i);;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment