89 lines
2.3 KiB
Dart
89 lines
2.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
class PluriMarkdown extends StatelessWidget {
|
|
const PluriMarkdown(this.markdown, {super.key});
|
|
|
|
final String markdown;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final widgets = <Widget>[];
|
|
for (final raw in markdown.split('\n')) {
|
|
final line = raw.trimRight();
|
|
if (line.trim().isEmpty) {
|
|
widgets.add(const SizedBox(height: 8));
|
|
} else if (line.startsWith('# ')) {
|
|
widgets.add(_Heading(line.substring(2), level: 1));
|
|
} else if (line.startsWith('## ')) {
|
|
widgets.add(_Heading(line.substring(3), level: 2));
|
|
} else if (line.startsWith('- ')) {
|
|
widgets.add(_Bullet(line.substring(2)));
|
|
} else if (!line.toLowerCase().startsWith('resumen:') &&
|
|
!line.toLowerCase().startsWith('summary:')) {
|
|
widgets.add(_Paragraph(line));
|
|
}
|
|
}
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: widgets,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _Heading extends StatelessWidget {
|
|
const _Heading(this.text, {required this.level});
|
|
|
|
final String text;
|
|
final int level;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
return Padding(
|
|
padding: EdgeInsets.only(top: level == 1 ? 0 : 14, bottom: 8),
|
|
child: Text(
|
|
text,
|
|
style: (level == 1
|
|
? theme.textTheme.headlineSmall
|
|
: theme.textTheme.titleMedium)
|
|
?.copyWith(fontWeight: FontWeight.w900),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _Paragraph extends StatelessWidget {
|
|
const _Paragraph(this.text);
|
|
|
|
final String text;
|
|
|
|
@override
|
|
Widget build(BuildContext context) => Padding(
|
|
padding: const EdgeInsets.only(bottom: 8),
|
|
child: Text(text, style: Theme.of(context).textTheme.bodyMedium),
|
|
);
|
|
}
|
|
|
|
class _Bullet extends StatelessWidget {
|
|
const _Bullet(this.text);
|
|
|
|
final String text;
|
|
|
|
@override
|
|
Widget build(BuildContext context) => Padding(
|
|
padding: const EdgeInsets.only(bottom: 8),
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Icon(
|
|
Icons.auto_awesome_rounded,
|
|
size: 18,
|
|
color: Theme.of(context).colorScheme.primary,
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(child: Text(text)),
|
|
],
|
|
),
|
|
);
|
|
}
|