showMarkdownFile function

FutureBuilder showMarkdownFile(
  1. BuildContext context,
  2. String markdownFilePath, [
  3. String svgAsset = 'assets/svg/generic.svg'
])

20241215 gjw A scrolling widget that parses and displays Markdown file, which is located under the path markdownFilePath. The markdown file takes up the left half of the widget while an optional SVG image the right ahlf. A generic image is displayed if no image is provided. It allows handling asynchronous loading of markdown file.

Implementation

FutureBuilder showMarkdownFile(
  BuildContext context,
  String markdownFilePath, [
  String svgAsset = 'assets/svg/generic.svg',
]) {
  return FutureBuilder(
    key: const Key('markdown_file'),
    future: loadAsset(markdownFilePath),
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        return Container(
          decoration: sunkenBoxDecoration,

          // 20241215 gjw It is easier to read the overview text when it is not
          // too wide. For now, and assuming the default window width, place the
          // Markdown text into a row and half fill the row.

          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // The text goes into the left pane.

              Expanded(
                child: Markdown(
                  data: snapshot.data!,
                  selectable: true,
                  onTapLink: (text, href, title) {
                    final Uri url = Uri.parse(href ?? '');
                    launchUrl(url);
                  },

                  // Custom image builder to load assets.

                  imageBuilder: (uri, title, alt) {
                    return Image.asset('$assetsPath/${uri.toString()}');
                  },
                ),
              ),

              // 20241215 gjw The right pane is for an image.

              Expanded(
                child: SvgPicture.asset(
                  svgAsset,
                  width: 300, // You can adjust these dimensions
                  height: 500, // to fit your needs
                  fit: BoxFit.contain,
                ),
              ),
            ],
          ),
        );
      }

      return const Center(child: CircularProgressIndicator());
    },
  );
}