Repository: flutter
Issue: [flutter_markdown] Crash if using `> [!NOTE]` syntax because custom block builders do not work
Labels: package,a: error message,team-ecosystem,has reproducible steps,P2,p: flutter_markdown,triaged-ecosystem,found in release: 3.22,found in release: 3.24

### Steps to reproduce

I'm using `markdown` 7.2.2 and `flutter_markdown` 0.7.3.

This minimal example crashes:
```dart
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:markdown/markdown.dart' as md;

void main() {
  runApp(MaterialApp(
    home: Scaffold(
      body: Markdown(
        data: '''
> [!NOTE]
> this does not work
''',
        extensionSet: md.ExtensionSet.gitHubWeb,
      ),
    ),
  ));
}
```

It throws a null pointer exception in
```
  void _addParentInlineIfNeeded(String? tag) {
    if (_inlines.isEmpty) {
      _inlines.add(_InlineElement(
        tag,
        style: styleSheet.styles[tag!], <------ here
      ));
    }
  }
```

because the markdown builder cannot deal with the 
```
    <div class="markdown-alert markdown-alert-note">
      <p class="markdown-alert-title">Note</p>
      <p>this does not work</p>
    </div>
```
generated by the markdown parser. It doesn't know the `div` element and thinks that it is an inline element and looses track of the `tag` and tries to lookup with `null` (why does this method accept a `String?` if the only use of that parameter requires a `!`?).

Theoretically, you can add `builders` to the `Markdown` widget like this one:

```dart
class NoteBuilder extends MarkdownElementBuilder {
  NoteBuilder();

  @override
  bool isBlockElement() => true;

  @override
  Widget? visitElementAfterWithContext(
    BuildContext context,
    md.Element element,
    TextStyle? preferredStyle,
    TextStyle? parentStyle,
  ) {
    throw UnimplementedError();
  }
}
```

However, the method to actually build a `Widget` is never called because the `MarkdownBuilder` class doesn't know about its configured builders in case of block elements. Those builders only work for inline elements and only the `visitText` method is ever called and this obviously doesn't work here, even if I'd lie about a note being a block level element.

### Expected results

`visitElementAfterWithContext` should be called so that I can attempt to build UI for the `div`.

It looks like the `MarkdownBuilder` calls `isBlockElement` for each passed `MarkdownElementBuilder`, patching a global variable that "knows" wich elements are block-level elements and which are not (why is this list global? As nobody ever removes elements from that global list, a bug can occur if two different `Markdown` widget has different kind of builders which try to register a builder called `x` both as a block and as an inline `x` but that's not the point here) but then, in `visitElementAfter` there's just a long `if/else if` list of well known elements and custom builders are completely ignored. Something like

```dart
if (builders.containsKey(tag) {
  child = builders[tag]!.visitElementAfterWithContext(...);
}
```
is missing in the code as the last `else`.

And if you're on it, please use modern Dart like
```dart
if (builders[tag] case final builder?) {
  child = builder.visitElementAfterWithContext(...);
}
```
here and at other places.

**However**, even if you'd call the method, it still is broken, as the API doesn't allow me to create a container `Widget` as I'd have to access to the element's children which have been already build recursively, I think. So, perhaps just owning the fact that custom builders are impossible would be the better fix. It would have saved me a couple of hours of debugging.

Or, have `BlockBuilder` and `InlineBuilder` instead, using them internally too, so that we can not only extend the `MarkdownBuilder` with new builders but also override or customize existing builders like for example `blockquote`.

### Actual results

I'd like to extend the `MarkdownBuilder`. Frankly, I don't care about the note syntax, I wanted to support a `<center>` widget to center parts of a markdown document. Writing a `BlockSyntax` subclass to introduce a `center` element to the markdown `Node` hierarchy is quite easy. However, you cannot make it work in Flutter.

### Code sample

see above

### Screenshots or Video

n/a

### Logs

n/a

### Flutter Doctor output

<details open><summary>Doctor output</summary>

```console
[✓] Flutter (Channel master, 3.24.0-1.0.pre.197, on macOS 14.5 23F79 darwin-x64, locale de-DE)
    • Flutter version 3.24.0-1.0.pre.197 on channel master at /Users/sma/Work/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 0bac2be379 (2 days ago), 2024-07-19 00:15:26 -0400
    • Engine revision ea1e53a4e8
    • Dart version 3.6.0 (build 3.6.0-55.0.dev)
    • DevTools version 2.37.1
```

I'm using `markdown` 7.2.2 and `flutter_markdown` 0.7.3.

</details>