build method
The final step in the chain. Converts the StyledElement tree, with its
attached Style
elements, into an InlineSpan
tree that includes
Widget/TextSpans that can be rendered in a RichText widget.
Implementation
@override
InlineSpan build(ExtensionContext context) {
StyledElement? node;
List<Widget> widgets = <Widget>[];
final rubySize = context.parser.style['rt']?.fontSize?.value ??
max(9.0, context.styledElement!.style.fontSize!.value / 2);
final rubyYPos = rubySize + rubySize / 2;
List<StyledElement> children = [];
context.styledElement!.children.forEachIndexed((index, element) {
if (!((element is TextContentElement) &&
(element.text ?? "").trim().isEmpty &&
index > 0 &&
index + 1 < context.styledElement!.children.length &&
context.styledElement!.children[index - 1] is! TextContentElement &&
context.styledElement!.children[index + 1] is! TextContentElement)) {
children.add(element);
}
});
for (var c in children) {
if (c.name == "rt" && node != null) {
final widget = Stack(
alignment: Alignment.center,
children: <Widget>[
Container(
alignment: Alignment.bottomCenter,
child: Center(
child: Transform(
transform: Matrix4.translationValues(0, -(rubyYPos), 0),
child: CssBoxWidget(
style: c.style,
child: Text(
c.element!.innerHtml,
style: c.style
.generateTextStyle()
.copyWith(fontSize: rubySize),
),
),
),
),
),
CssBoxWidget(
style: context.styledElement!.style,
child: node is TextContentElement
? Text(
node.text?.trim() ?? "",
style: context.styledElement!.style.generateTextStyle(),
)
: RichText(
text: const TextSpan(
text:
'!rc!')), // TODO was context.parser.parseTree(context, node)),
),
],
);
widgets.add(widget);
} else {
node = c;
}
}
return WidgetSpan(
alignment: (context.styledElement! as ReplacedElement).alignment,
baseline: TextBaseline.alphabetic,
child: Padding(
padding: EdgeInsets.only(top: rubySize),
child: Wrap(
key: AnchorKey.of(context.parser.key, context.styledElement),
runSpacing: rubySize,
children: widgets.map((e) {
return Row(
crossAxisAlignment: CrossAxisAlignment.end,
textBaseline: TextBaseline.alphabetic,
mainAxisSize: MainAxisSize.min,
children: [e],
);
}).toList(),
),
),
);
}