【发布时间】:2020-01-04 16:28:35
【问题描述】:
我正在使用 flutter_markdown 包为我的应用添加降价支持。 syntaxHighlighter 有一个选项。我找到了一个 syntax highlight library 我如何使用它来帮助编写我的 SyntaxHighlighter 类
【问题讨论】:
标签: flutter dart flutter-dependencies
我正在使用 flutter_markdown 包为我的应用添加降价支持。 syntaxHighlighter 有一个选项。我找到了一个 syntax highlight library 我如何使用它来帮助编写我的 SyntaxHighlighter 类
【问题讨论】:
标签: flutter dart flutter-dependencies
我刚刚写了一个问题:)
请查看Feature: Get Syntax Language when customizing properties syntaxHighlighter #355.
这是该期的内容。
问题 #227 StackOverflow - How to add code syntax highlighter to flutter markdown
处理语法语言突出显示。
取决于highlight,当然还有flutter_markdown。
首先,在将数据传递给Markdown之前,使用RegExp获取语法语言。
第二,用相同的LANG_MARKER标记语言,例如L@NG!。
这是一个示例代码。
String parseSyntaxLanguage(String data) {
String parsed = data;
RegExp codeSign = new RegExp(r'`{3} *');
RegExp pattern = new RegExp(r'`{3} *[\w]+');
for (RegExpMatch match in pattern.allMatches(this.data)) {
String lang = match.group(0).split(codeSign)[1]; // get a syntax language
parsed = parsed.replaceFirst(match.group(0), '```\n$LANG_MARKER$lang$LANG_MARKER');
} // CAUTION "\n" newline is required!
return parsed;
}
第三,做一个语法高亮扩展SyntaxHighlighter
这是一个示例代码。
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:highlight/highlight.dart' show highlight, Node;
class LangSyntaxHighlighter extends SyntaxHighlighter {
final String language;
final String _rootKey = 'root';
final String _defaultLang = 'dart';
final String _defaultFontFamily = 'monospace';
final Color _defaultFontColor = Color(0xfffdfeff);
final Map<String, TextStyle> theme; // User's code theme
LangSyntaxHighlighter(this.theme);
@override
TextSpan format(String source) {
String lang;
if (source.startsWith(LANG_MARKER)) {
int idx = source.indexOf(LANG_MARKER, LANG_MARKER.length);
lang = source.substring(LANG_MARKER.length, idx);
source = source.substring(idx + LANG_MARKER.length);
}
TextStyle _textStyle = TextStyle(
fontFamily: this._defaultFontFamily,
color: this.theme[this._rootKey].color ?? this._defaultFontColor,
);
return TextSpan(
style: _textStyle,
children: this._convert(highlight
.parse(source, autoDetection: true, language: lang ?? this._defaultLang)
.nodes),
);
}
List<TextSpan> _convert(List<Node> nodes) {
List<TextSpan> spans = [];
var currentSpans = spans;
List<List<TextSpan>> stack = [];
_traverse(Node node) {
if (node.value != null) {
currentSpans.add(node.className == null
? TextSpan(text: node.value)
: TextSpan(text: node.value, style: theme[node.className]));
} else if (node.children != null) {
List<TextSpan> tmp = [];
currentSpans.add(TextSpan(children: tmp, style: theme[node.className]));
stack.add(currentSpans);
currentSpans = tmp;
node.children.forEach((n) {
_traverse(n);
if (n == node.children.last)
currentSpans = stack.isEmpty ? spans : stack.removeLast();
});
}
}
for (var node in nodes) _traverse(node);
return spans;
}
}
最后,结合语法高亮和解析器。
Widget build(BuildContext context) {
Future<Widget> parseMarkdown = new Future(() {
return MarkdownBody(
data: parseSyntaxLanguage(this.data), // markdown source
syntaxHighlighter: LangSyntaxHighlighter(),
styleSheet: MarkdownStyleSheet(
...
我不确定这是否适合功能请求。 但是,我希望这个问题对某人有所帮助:)
【讨论】:
我能够使用flutter_highlighter、flutter_markdown 提出解决方案,并使用Google Fonts 作为等宽字体。
首先您需要创建一个元素构建器来操作Markdown 小部件中的代码块。
import 'package:flutter_highlighter/flutter_highlighter.dart';
import 'package:flutter_highlighter/themes/atom-one-dark.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:markdown/markdown.dart' as md;
import 'package:google_fonts/google_fonts.dart';
class CodeElementBuilder extends MarkdownElementBuilder {
@override
Widget? visitElementAfter(md.Element element, TextStyle? preferredStyle) {
var language = '';
if (element.attributes['class'] != null) {
String lg = element.attributes['class'] as String;
language = lg.substring(9);
}
return SizedBox(
width:
MediaQueryData.fromWindow(WidgetsBinding.instance!.window).size.width,
child: HighlightView(
// The original code to be highlighted
element.textContent,
// Specify language
// It is recommended to give it a value for performance
language: language,
// Specify highlight theme
// All available themes are listed in `themes` folder
theme: MediaQueryData.fromWindow(WidgetsBinding.instance!.window)
.platformBrightness ==
Brightness.light
? atomOneLightTheme
: atomOneDarkTheme,
// Specify padding
padding: const EdgeInsets.all(8),
// Specify text style
textStyle: GoogleFonts.robotoMono(),
),
);
}
}
接下来,您需要将上面的元素构建器添加到 Markdown 内的构建器中:
Markdown(
key: const Key("defaultmarkdownformatter"),
data: codeText,
selectable: true,
padding: const EdgeInsets.all(10),
builders: {
'code': CodeElementBuilder(),
}),
你应该很高兴。
【讨论】: