如何为flutter-markdown添加自定义标签支持以实现指定格式超链接?
实现自定义[[id,text]]标签的方案
无需同时修改flutter_markdown和markdown两个库的底层源码,直接利用两个库开放的扩展能力即可实现需求,步骤如下:
1. 基于markdown库实现自定义语法解析器
继承markdown库的InlineSyntax类,匹配[[id,text]]格式的自定义标签,解析出id和text字段生成自定义节点:
import 'package:markdown/markdown.dart' as md; class CustomLinkSyntax extends md.InlineSyntax { // 正则可根据实际id、text的格式规则调整 CustomLinkSyntax() : super(r'\[\[(\w+),([^\]]+)\]\]'); @override bool onMatch(md.InlineParser parser, Match match) { final id = match.group(1)!; final text = match.group(2)!; // 生成自定义节点,tag名可自行定义 final element = md.Element('custom_link', [md.Text(text)]); element.attributes['id'] = id; element.attributes['text'] = text; parser.addNode(element); return true; } }
2. 基于flutter_markdown实现自定义节点构建器
继承MarkdownElementBuilder,识别上面生成的custom_link节点,渲染为可点击的超链接组件:
import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:url_launcher/url_launcher.dart'; class CustomLinkBuilder extends MarkdownElementBuilder { @override Widget? visitElementAfter(md.Element element, TextStyle? preferredStyle) { if (element.tag == 'custom_link') { final id = element.attributes['id']!; final text = element.attributes['text']!; final targetUrl = 'abc.com/$id/$text'; return GestureDetector( onTap: () async { // 自行实现跳转逻辑 final uri = Uri.parse(targetUrl); if (await canLaunchUrl(uri)) { await launchUrl(uri); } }, child: Text( text, style: preferredStyle?.copyWith( color: Colors.blue, decoration: TextDecoration.underline, ), ), ); } return null; } }
3. 注入扩展到FlutterMarkdown组件
使用组件时将自定义语法和构建器传入对应参数即可生效,注意要保留默认语法集合,避免原生Markdown格式失效:
FlutterMarkdown( data: '你的markdown内容,包含[[123,测试链接]]这类标签', syntaxes: [ CustomLinkSyntax(), // 保留GitHub Flavored Markdown默认语法 ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes, ], builders: { 'custom_link': CustomLinkBuilder(), }, )
如果需要适配更多格式规则,比如标签内允许空格、id支持特殊字符等,仅需修改
CustomLinkSyntax中的正则表达式即可,无需改动其他逻辑。
内容的提问来源于stack exchange,提问作者Sandeep
相关产品推荐
相关产品推荐

