This commit is contained in:
toly
2020-04-13 16:06:43 +08:00
parent 8c02114982
commit 0dfe274d18
149 changed files with 3611 additions and 3021 deletions

View File

@@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
import 'high_light_code.dart';
import 'highlighter_style.dart';
class CodeWidget extends StatelessWidget {
CodeWidget({Key key, @required this.code, this.style, this.fontSize = 13,this.fontFamily})
: super(key: key);
final String code;
final HighlighterStyle style;
final double fontSize;
final String fontFamily;
@override
Widget build(BuildContext context) {
Widget body;
if (code == null) {
return Container();
} else {
Widget _codeWidget;
try {
_codeWidget = RichText(
text: TextSpan(
style: TextStyle(fontSize: fontSize,fontFamily: fontFamily),
children: <TextSpan>[DartHighlighter(style).format(code)],
),
);
} catch (err) {
_codeWidget = Text(code);
}
body = SingleChildScrollView(
child: Container(
child: _codeWidget,
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: style.backgroundColor ?? Color(0xffF6F8FA),
borderRadius: BorderRadius.all(Radius.circular(5.0))),
),
);
}
return body;
}
}

View File

@@ -0,0 +1,316 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:string_scanner/string_scanner.dart';
import 'highlighter_style.dart';
/// final SyntaxHighlighterStyle style = SyntaxHighlighterStyle.lightThemeStyle();
/// DartSyntaxHighlighter(style).format(source)
abstract class Highlighter { // ignore: one_member_abstracts
TextSpan format(String src);
}
//暗黑模式下的高亮样式
class DartHighlighter extends Highlighter {
DartHighlighter([this._style]) {
_spans = <_HighlightSpan>[];
_style ??= HighlighterStyle.fromColors(HighlighterStyle.lightColor);
}
HighlighterStyle _style;
static const List<String> _keywords = <String>[
'abstract', 'as', 'assert', 'async', 'await', 'break', 'case', 'catch',
'class', 'const', 'continue', 'default', 'deferred', 'do', 'dynamic', 'else',
'enum', 'export', 'external', 'extends', 'factory', 'false', 'final',
'finally', 'for', 'get', 'if', 'implements', 'import', 'in', 'is', 'library',
'new', 'null', 'operator', 'part', 'rethrow', 'return', 'set', 'static',
'super', 'switch', 'sync', 'this', 'throw', 'true', 'try', 'typedef', 'var',
'void', 'while', 'with', 'yield'
];
static const List<String> _builtInTypes = <String>[
'int', 'double', 'num', 'bool'
];
String _src;
StringScanner _scanner;
List<_HighlightSpan> _spans;
@override
TextSpan format(String src) {
_src = src;
_scanner = StringScanner(_src);
if (_generateSpans()) {
// Successfully parsed the code
final List<TextSpan> formattedText = <TextSpan>[];
int currentPosition = 0;
for (_HighlightSpan span in _spans) {
if (currentPosition != span.start)
formattedText.add(TextSpan(text: _src.substring(currentPosition, span.start)));
formattedText.add(TextSpan(style: span.textStyle(_style), text: span.textForSpan(_src)));
currentPosition = span.end;
}
if (currentPosition != _src.length)
formattedText.add(TextSpan(text: _src.substring(currentPosition, _src.length)));
return TextSpan(style: _style.baseStyle, children: formattedText);
} else {
// Parsing failed, return with only basic formatting
return TextSpan(style: _style.baseStyle, text: src);
}
}
bool _generateSpans() {
int lastLoopPosition = _scanner.position;
while (!_scanner.isDone) {
// Skip White space
_scanner.scan(RegExp(r'\s+'));
// Block comments
if (_scanner.scan(RegExp(r'/\*(.|\n)*\*/'))) {
_spans.add(_HighlightSpan(
_HighlightType.comment,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Line comments
if (_scanner.scan('//')) {
final int startComment = _scanner.lastMatch.start;
bool eof = false;
int endComment;
if (_scanner.scan(RegExp(r'.*\n'))) {
endComment = _scanner.lastMatch.end - 1;
} else {
eof = true;
endComment = _src.length;
}
_spans.add(_HighlightSpan(
_HighlightType.comment,
startComment,
endComment
));
if (eof)
break;
continue;
}
// Raw r"String"
if (_scanner.scan(RegExp(r'r".*"'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Raw r'String'
if (_scanner.scan(RegExp(r"r'.*'"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Multiline """String"""
if (_scanner.scan(RegExp(r'"""(?:[^"\\]|\\(.|\n))*"""'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Multiline '''String'''
if (_scanner.scan(RegExp(r"'''(?:[^'\\]|\\(.|\n))*'''"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// "String"
if (_scanner.scan(RegExp(r'"(?:[^"\\]|\\.)*"'))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// 'String'
if (_scanner.scan(RegExp(r"'(?:[^'\\]|\\.)*'"))) {
_spans.add(_HighlightSpan(
_HighlightType.string,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Double
if (_scanner.scan(RegExp(r'\d+\.\d+'))) {
_spans.add(_HighlightSpan(
_HighlightType.number,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Integer
if (_scanner.scan(RegExp(r'\d+'))) {
_spans.add(_HighlightSpan(
_HighlightType.number,
_scanner.lastMatch.start,
_scanner.lastMatch.end)
);
continue;
}
// Punctuation
if (_scanner.scan(RegExp(r'[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]'))) {
_spans.add(_HighlightSpan(
_HighlightType.punctuation,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Meta data
if (_scanner.scan(RegExp(r'@\w+'))) {
_spans.add(_HighlightSpan(
_HighlightType.keyword,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
continue;
}
// Words
if (_scanner.scan(RegExp(r'\w+'))) {
_HighlightType type;
String word = _scanner.lastMatch[0];
if (word.startsWith('_'))
word = word.substring(1);
if (_keywords.contains(word))
type = _HighlightType.keyword;
else if (_builtInTypes.contains(word))
type = _HighlightType.keyword;
else if (_firstLetterIsUpperCase(word))
type = _HighlightType.klass;
else if (word.length >= 2 && word.startsWith('k') && _firstLetterIsUpperCase(word.substring(1)))
type = _HighlightType.constant;
if (type != null) {
_spans.add(_HighlightSpan(
type,
_scanner.lastMatch.start,
_scanner.lastMatch.end
));
}
}
// Check if this loop did anything
if (lastLoopPosition == _scanner.position) {
// Failed to parse this file, abort gracefully
return false;
}
lastLoopPosition = _scanner.position;
}
_simplify();
return true;
}
void _simplify() {
for (int i = _spans.length - 2; i >= 0; i -= 1) {
if (_spans[i].type == _spans[i + 1].type && _spans[i].end == _spans[i + 1].start) {
_spans[i] = _HighlightSpan(
_spans[i].type,
_spans[i].start,
_spans[i + 1].end
);
_spans.removeAt(i + 1);
}
}
}
bool _firstLetterIsUpperCase(String str) {
if (str.isNotEmpty) {
final String first = str.substring(0, 1);
return first == first.toUpperCase();
}
return false;
}
}
enum _HighlightType {
number,
comment,
keyword,
string,
punctuation,
klass,
constant
}
class _HighlightSpan {
_HighlightSpan(this.type, this.start, this.end);
final _HighlightType type;
final int start;
final int end;
String textForSpan(String src) {
return src.substring(start, end);
}
TextStyle textStyle(HighlighterStyle style) {
if (type == _HighlightType.number)
return style.numberStyle;
else if (type == _HighlightType.comment)
return style.commentStyle;
else if (type == _HighlightType.keyword)
return style.keywordStyle;
else if (type == _HighlightType.string)
return style.stringStyle;
else if (type == _HighlightType.punctuation)
return style.punctuationStyle;
else if (type == _HighlightType.klass)
return style.classStyle;
else if (type == _HighlightType.constant)
return style.constantStyle;
else
return style.baseStyle;
}
}

View File

@@ -0,0 +1,136 @@
import 'package:flutter/material.dart';
/// create by 张风捷特烈 on 2020-04-11
/// contact me by email 1981462002@qq.com
/// 说明:
class HighlighterStyle {
//句法高亮样式
const HighlighterStyle(
{ //构造函数
this.baseStyle, //基础样式
this.numberStyle, //数字的样式
this.commentStyle, //注释样式
this.keywordStyle, //关键字样式
this.stringStyle, //字符串样式
this.punctuationStyle, //标点符号样式
this.classStyle, //类名
this.backgroundColor,
this.constantStyle});
static List<int> get lightColor => [
0xFF000000, //基础
0xFF00b0e8, //数字
0xFF9E9E9E, //注释
0xFF9C27B0, //关键
0xFF43A047, //字符串
0xFF000000, //标点符号
0xFF3D62F5, //类名
0xFF795548, //常量
0xffF6F8FA, //背景
];
static List<int> get darkColor => [
0xFFFFFFFF, //基础
0xFFDF935F, //数字
0xFF9E9E9E, //注释
0xFF80CBC4, //关键字
0xFFB9CA4A, //字符串
0xFFFFFFFF, //标点符号
0xFF7AA6DA, //类名
0xFF795548, //常量
0xFF1D1F21, //背景
];
static List<int> get gitHub =>
[
0xFF333333, //基础
0xFF008081, //数字
0xFF9D9D8D, //注释
0xFF009999, //关键字
0xFFDD1045, //字符串
0xFF333333, //标点符号
0xFF6F42C1, //类名
0xFF795548, //常量
0xFFF8F8F8, //背景
];
static List<int> get zenburn => [
0xFFDCDCDC, //普通字
0xFF87C5C8, //数字
0xFF8F8F8F, //注释
0xFFE4CEAB, //关键字
0xFFCC9493, //字符串
0xFFDCDCDC, //标点符号
0xFFEFEF90, //类名
0xFFEF5350, //常量
0xFF3F3F3F, //背景
];
static List<int> get mf =>[
0xFF707D95, //基础
0xFF6897BB, //数字
0xFF629755, //注释
0xFFCC7832, //关键
0xFFF14E9F, //字符串
0xFFFFBB33, //标点符号
0xFF66CCFF, //类名
0xFF9876AA, //常量
0xFF2B2B2B //背景
];
static List<int> get solarized =>[
0xFF657B83, // 普通字
0xFFD33682, // 数字
0xFF93A1A1, // 注释
0xFF859900, // 关键字
0xFF2AA198, // 字符串
0xFF859900, // 标点符号
0xFF268BD2, // 类名
0xFF268BD2, //常量
0xFFDDD6C1, // 背景
];
factory HighlighterStyle.fromColors(List<int> colors) => HighlighterStyle(
baseStyle: TextStyle(
color: Color(colors[0]),
),
numberStyle: TextStyle(
color: Color(colors[1]),
),
commentStyle: TextStyle(
color: Color(
colors[2],
),
fontStyle: FontStyle.italic),
keywordStyle: TextStyle(
fontWeight: FontWeight.bold,
color: Color(
colors[3],
),
),
stringStyle: TextStyle(
color: Color(colors[4]),
),
punctuationStyle: TextStyle(
color: Color(colors[5]),
),
classStyle: TextStyle(
color: Color(colors[6]),
),
constantStyle: TextStyle(
color: Color(colors[7]),
),
backgroundColor: Color(colors[8]),
);
final TextStyle baseStyle;
final TextStyle numberStyle;
final TextStyle commentStyle;
final TextStyle keywordStyle;
final TextStyle stringStyle;
final TextStyle punctuationStyle;
final TextStyle classStyle;
final TextStyle constantStyle;
final Color backgroundColor;
}