【问题标题】:How to add code syntax highlighter to flutter_markdown如何将代码语法高亮添加到flutter_markdown
【发布时间】:2020-01-04 16:28:35
【问题描述】:

我正在使用 flutter_markdown 包为我的应用添加降价支持。 syntaxHighlighter 有一个选项。我找到了一个 syntax highlight library 我如何使用它来帮助编写我的 SyntaxHighlighter 类

【问题讨论】:

    标签: flutter dart flutter-dependencies


    【解决方案1】:

    我刚刚写了一个问题:)

    请查看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(
        
             ...
    
    
    

    我不确定这是否适合功能请求。 但是,我希望这个问题对某人有所帮助:)

    【讨论】:

    • 感谢您的解决方案,但我们如何将其与现有的文本字段小部件一起使用,以像 IDE/代码编辑器一样实时解析和突出显示代码。
    【解决方案2】:

    我能够使用flutter_highlighterflutter_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(),
        
      }),
    

    你应该很高兴。

    【讨论】:

      猜你喜欢
      • 2014-02-04
      • 1970-01-01
      • 2013-02-07
      • 2019-01-23
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多