This commit is contained in:
toly
2023-12-16 12:40:32 +08:00
parent ab2778a22b
commit 01fdf966c5
593 changed files with 8995 additions and 27753 deletions

View File

@@ -0,0 +1,5 @@
export 'code_widget.dart';
export 'high_light_code.dart';
export 'highlighter_style.dart';
export 'language/language.dart';
export 'language/dart_languge.dart';

View File

@@ -0,0 +1,50 @@
/// create by 张风捷特烈 on 2020-04-15
/// contact me by email 1981462002@qq.com
/// 说明:
import 'package:flutter/material.dart';
import 'high_light_code.dart';
import 'highlighter_style.dart';
import 'language/dart_languge.dart';
class CodeWidget extends StatelessWidget {
CodeWidget({Key? key, required this.code,required 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;
Widget _codeWidget;
try {
_codeWidget = RichText(
text: TextSpan(
style: TextStyle(fontSize: fontSize,fontFamily: fontFamily),
children: <TextSpan>[
CodeHighlighter(
style: style,
language: const DartLanguage()
).format(code)],
),
);
} catch (err) {
print(err);
_codeWidget = Text(code);
}
body = SingleChildScrollView(
child: Container(
child: _codeWidget,
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: style.backgroundColor ?? const Color(0xffF6F8FA),
borderRadius: const BorderRadius.all(Radius.circular(5.0))),
),
);
return body;
}
}

View File

@@ -0,0 +1,275 @@
/// create by 张风捷特烈 on 2020-04-15
/// contact me by email 1981462002@qq.com
/// 说明:
// 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';
import 'language/dart_languge.dart';
import 'language/language.dart';
/// final SyntaxHighlighterStyle style = SyntaxHighlighterStyle.lightThemeStyle();
/// DartSyntaxHighlighter(style).format(source)
abstract class Highlighter {
// ignore: one_member_abstracts
Language language;
Highlighter({required this.language});
TextSpan format(String src);
}
//暗黑模式下的高亮样式
class CodeHighlighter extends Highlighter {
CodeHighlighter(
{Language language = const DartLanguage(), HighlighterStyle? style}):super(language: language) {
_spans = <_HighlightSpan>[];
_style = style ?? HighlighterStyle.fromColors(HighlighterStyle.lightColor);
}
late HighlighterStyle _style;
String _src='';
late 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??0, _scanner.lastMatch?.end??0));
continue;
}
// Line comments
if (_scanner.scan(RegExp(r'//'))) {
final int startComment = _scanner.lastMatch?.start??0;
bool eof = false;
int endComment;
if (_scanner.scan(RegExp(r'(.*\r\n)|(.*\n)'))) {
int? end = _scanner.lastMatch?.end;
endComment = end==null?0: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??0, _scanner.lastMatch?.end??0));
continue;
}
// Raw r'String'
if (_scanner.scan(RegExp(r"r'.*'"))) {
_spans.add(_HighlightSpan(_HighlightType.string,
_scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0));
continue;
}
// Multiline """String"""
if (_scanner.scan(RegExp(r'"""(?:[^"\\]|\\(.|\n))*"""'))) {
_spans.add(_HighlightSpan(_HighlightType.string,
_scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0));
continue;
}
// Multiline '''String'''
if (_scanner.scan(RegExp(r"'''(?:[^'\\]|\\(.|\n))*'''"))) {
_spans.add(_HighlightSpan(_HighlightType.string,
_scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0));
continue;
}
// "String"
if (_scanner.scan(RegExp(r'"(?:[^"\\]|\\.)*"'))) {
_spans.add(_HighlightSpan(_HighlightType.string,
_scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0));
continue;
}
// 'String'
if (_scanner.scan(RegExp(r"'(?:[^'\\]|\\.)*'"))) {
_spans.add(_HighlightSpan(_HighlightType.string,
_scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0));
continue;
}
// Double
if (_scanner.scan(RegExp(r'\d+\.\d+'))) {
_spans.add(_HighlightSpan(_HighlightType.number,
_scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0));
continue;
}
// Integer
if (_scanner.scan(RegExp(r'\d+'))) {
_spans.add(_HighlightSpan(_HighlightType.number,
_scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0));
continue;
}
// Punctuation
if (_scanner.scan(RegExp(r'[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]'))) {
_spans.add(_HighlightSpan(_HighlightType.punctuation,
_scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0));
continue;
}
// Meta data
if (_scanner.scan(RegExp(r'@\w+'))) {
_spans.add(_HighlightSpan(_HighlightType.keyword,
_scanner.lastMatch?.start??0, _scanner.lastMatch?.end??0));
continue;
}
// Words
if (_scanner.scan(RegExp(r'\w+'))) {
_HighlightType? type;
String word = _scanner.lastMatch?[0]??'';
if (word.startsWith('_')) word = word.substring(1);
if (language.containsKeywords(word)) {
type = _HighlightType.keyword;
} else if (language.containsInTypes(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??0, _scanner.lastMatch?.end??0));
}
}
// 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,139 @@
/// create by 张风捷特烈 on 2020-04-15
/// contact me by email 1981462002@qq.com
/// 说明:
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;
}

View File

@@ -0,0 +1,42 @@
import 'language.dart';
/// create by 张风捷特烈 on 2021/1/21
/// contact me by email 1981462002@qq.com
/// 说明:
class DartLanguage extends Language{
const DartLanguage() : super('Dart');
static const List<String> _kDartKeywords = [
'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> _kDartInTypes = [
'int', 'double', 'num', 'bool'
];
@override
List<String> get keywords => _kDartKeywords;
@override
List<String> get inTypes => <String>[
'int', 'double', 'num', 'bool'
];
@override
bool containsInTypes(String word) =>_kDartKeywords.contains(word);
@override
bool containsKeywords(String word)=>_kDartInTypes.contains(word);
}

View File

@@ -0,0 +1,17 @@
/// create by 张风捷特烈 on 2021/1/21
/// contact me by email 1981462002@qq.com
/// 说明:
abstract class Language {
final String name;
const Language(this.name);
bool containsKeywords(String word);
bool containsInTypes(String word);
List<String> get keywords;
List<String> get inTypes;
}