Skip to content

Latest commit

 

History

History
231 lines (168 loc) · 7.74 KB

File metadata and controls

231 lines (168 loc) · 7.74 KB

语言:简体中文 | English | 日本語

screen

📖markdown_widget

Coverage Status pub package demo

一个简单易用的markdown渲染组件

  • 支持TOC功能,可以通过Heading快速定位
  • 支持代码高亮
  • 支持全平台

🚀使用

在开始之前,你可以先体验一下在线 demo 点击体验

import 'package:flutter/material.dart';
import 'package:markdown_widget/markdown_widget.dart';

class MarkdownPage extends StatelessWidget {
  final String data;

  MarkdownPage(this.data);

  @override
  Widget build(BuildContext context) => Scaffold(body: buildMarkdown());

  Widget buildMarkdown() => MarkdownWidget(data: data);
}

如果你想使用自己的 Column 或者其他列表 Widget, 你可以使用 MarkdownGenerator

  Widget buildMarkdown() =>
      Column(children: MarkdownGenerator().buildWidgets(data));

或者直接使用 MarkdownBlock

  Widget buildMarkdown() =>
      SingleChildScrollView(child: MarkdownBlock(data: data));

📁 更多示例

更多高级用法示例,请参考仓库中的 example/lib/markdown_custom 文件夹:

  • video.dart - 自定义 video 标签支持
  • latex.dart - LaTeX 数学公式渲染
  • mermaid.dart - Mermaid 图表支持(流程图、时序图等)
  • html_support.dart - HTML 标签扩展
  • custom_node.dart - 自定义节点实现示例

这些示例展示了如何通过自定义标签和功能来扩展本包。

🌠夜间模式

markdown_widget 默认支持夜间模式,只需要使用不同的 MarkdownConfig 即可

  Widget buildMarkdown(BuildContext context) {
    final isDark = Theme.of(context).brightness == Brightness.dark;
    final config = isDark
        ? MarkdownConfig.darkConfig
        : MarkdownConfig.defaultConfig;
    final codeWrapper = (child, text, language) =>
        CodeWrapperWidget(child, text, language);
    return MarkdownWidget(
        data: data,
        config: config.copy(configs: [
        isDark
        ? PreConfig.darkConfig.copy(wrapper: codeWrapper)
        : PreConfig().copy(wrapper: codeWrapper)
    ]));
  }
默认模式 夜间模式

🔗链接

你可以自定义链接样式和点击事件,比如下面这样

  Widget buildMarkdown() => MarkdownWidget(
      data: data,
      config: MarkdownConfig(configs: [
        LinkConfig(
          style: TextStyle(
            color: Colors.red,
            decoration: TextDecoration.underline,
          ),
          onTap: (url) {
            ///TODO:on tap
          },
        )
      ]));
      

📜TOC功能

使用TOC非常的简单

  final tocController = TocController();

  Widget buildTocWidget() => TocWidget(controller: tocController);

  Widget buildMarkdown() => MarkdownWidget(data: data, tocController: tocController);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Row(
          children: <Widget>[
            Expanded(child: buildTocWidget()),
            Expanded(child: buildMarkdown(), flex: 3)
          ],
        ));
  }

🎈代码高亮

代码高亮支持多种主题

import 'package:flutter_highlight/themes/a11y-light.dart';

  Widget buildMarkdown() => MarkdownWidget(
      data: data,
      config: MarkdownConfig(configs: [
        PreConfig(theme: a11yLightTheme),
      ]));

🧬全选与复制

支持全平台的全选和复制功能

image

🌐html 标签

由于当前 package 只实现了对于 Markdown tag 的转换,所以默认不支持转换 html 标签。但可以通过扩展的方式来支持这个功能,具体可以参考这里的使用 html_support.dart

以及 在线html demo展示

🧮Latex 支持

在例子中实现了对于Latex的简单支持,具体可以参考这里的实现 latex.dart

以及 在线latex demo展示

🔷Mermaid 图表支持

示例中包含了对 Mermaid 图表的支持,可以渲染流程图、时序图、状态图等。具体实现可以参考 mermaid.dart

特性:

  • 支持多种图表类型(流程图、时序图、状态图、ER 图等)
  • 支持主题切换(自动跟随明暗模式)
  • 交互式显示模式(仅代码、仅图表、或两者)
  • 全屏查看器,支持平移和缩放
  • 宽图表独立水平滚动
  • 智能缓存和防抖,优化性能

以及 在线Mermaid demo展示

import 'package:markdown_widget/markdown_widget.dart';
import 'markdown_custom/mermaid.dart';

// 基本用法
final isDark = Theme.of(context).brightness == Brightness.dark;
final preConfig = PreConfig(
  wrapper: createMermaidWrapper(
    config: const MermaidConfig(),
    isDark: isDark,
    preConfig: preConfig,
  ),
);

MarkdownWidget(
  data: markdown,
  config: config.copy(configs: [preConfig]),
)

// 自定义配置
final preConfig = PreConfig(
  wrapper: createMermaidWrapper(
    config: MermaidConfig(
      displayMode: MermaidDisplayMode.codeAndDiagram,
      diagramPadding: EdgeInsets.all(16.0),
      showLoadingIndicator: true,
    ),
    isDark: isDark,
    preConfig: preConfig,
  ),
);

🍑自定义tag与实现

通过向 MarkdownGeneratorConfig 传递 SpanNodeGeneratorWithTag ,可以增加新的 tag,以及这个 tag 所对应的 SpanNode;也可以使用已有的 tag 来对它所对应的 SpanNode 进行覆盖

同时也可以通过 InlineSyntaxBlockSyntax 自定义 markdown 字符串的解析规则,并生成新的 tag

可以参考 这个issue 是如何去实现一个自定义tag的

如果你由什么好的想法或者建议,以及使用上的问题, 欢迎来提pr或issue

🧾附录

这里是 markdown_widget 中使用到的其他库

描述
markdown 解析markdown数据
flutter_highlight 代码高亮
highlight 代码高亮
url_launcher 用于打开链接
visibility_detector 监听Widget是否可见
scroll_to_index 让Listview可以根据index来跳转