Html conventor package

pull/1523/head
Ellet 1 year ago
parent 78e48eb49b
commit b07b26326b
No known key found for this signature in database
GPG Key ID: C488CC70BBCEF0D1
  1. 34
      example/lib/pages/home_page.dart
  2. 6
      example/pubspec.yaml
  3. 8
      packages/README.md
  4. 30
      packages/flutter_quill_html/.gitignore
  5. 10
      packages/flutter_quill_html/.metadata
  6. 3
      packages/flutter_quill_html/CHANGELOG.md
  7. 1
      packages/flutter_quill_html/LICENSE
  8. 23
      packages/flutter_quill_html/README.md
  9. 36
      packages/flutter_quill_html/analysis_options.yaml
  10. 1
      packages/flutter_quill_html/delta_markdown
  11. 132
      packages/flutter_quill_html/lib/flutter_quill_html.dart
  12. 38
      packages/flutter_quill_html/pubspec.yaml
  13. 3
      packages/flutter_quill_html/pubspec_overrides.yaml.g
  14. 7
      packages/flutter_quill_html/test/flutter_quill_html_test.dart
  15. 5
      scripts/disable_local_dev.sh
  16. 5
      scripts/enable_local_dev.sh

@ -15,6 +15,7 @@ import 'package:flutter_quill/flutter_quill.dart';
import 'package:flutter_quill_extensions/flutter_quill_extensions.dart';
import 'package:flutter_quill_extensions/logic/services/image_picker/image_picker.dart';
import 'package:flutter_quill_extensions/presentation/embeds/widgets/image.dart';
import 'package:flutter_quill_html/flutter_quill_html.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
@ -120,10 +121,12 @@ class _HomePageState extends State<HomePage> {
),
),
IconButton(
onPressed: () => _insertTimeStamp(
_controller,
DateTime.now().toString(),
),
onPressed: () {
_insertTimeStamp(
_controller,
DateTime.now().toString(),
);
},
icon: const Icon(Icons.add_alarm_rounded),
),
IconButton(
@ -264,6 +267,29 @@ class _HomePageState extends State<HomePage> {
}
},
),
ListTile(
title: const Text('Convert to/from HTML'),
onTap: () async {
final scaffoldMessenger = ScaffoldMessenger.of(context);
final navigator = Navigator.of(context);
try {
final html = _controller.document.toDelta().toHtml();
print(html);
_controller.document =
Document.fromDelta(DeltaHtmlExt.fromHtml(html));
} catch (e) {
scaffoldMessenger.showSnackBar(
SnackBar(
content: Text(
'Error while convert to/from HTML: ${e.toString()}',
),
),
);
} finally {
navigator.pop();
}
},
),
_buildMenuBar(context),
],
),

@ -17,8 +17,10 @@ dependencies:
path_provider: ^2.1.1
# filesystem_picker: ^4.0.0
file_picker: ^6.1.1
flutter_quill: ^8.4.1
flutter_quill_extensions: ^0.6.5
flutter_quill: ^8.5.1
flutter_quill_extensions: ^0.6.7
flutter_quill_html:
path: ../packages/flutter_quill_html
path: ^1.8.3
desktop_drop: ^0.4.4
image_cropper: ^5.0.0

@ -3,4 +3,10 @@
This folder contains packages that add more features to the [FlutterQuill](../README.md)
that might be outside of the packages main purpose
This page will be updated soon.
## Table of contents
- [Flutter Quill Packages](#flutter-quill-packages)
- [Table of contents](#table-of-contents)
- [Packages](#packages)
## Packages
- [flutter_quill_html](./flutter_quill_html/)

@ -0,0 +1,30 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.packages
build/

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "d211f42860350d914a5ad8102f9ec32764dc6d06"
channel: "stable"
project_type: package

@ -0,0 +1,3 @@
## 0.0.1
* TODO: Describe initial release.

@ -0,0 +1 @@
TODO: Add your license here.

@ -0,0 +1,23 @@
# Flutter Quill HTML
A extension for [flutter_quill](https://pub.dev/packages/flutter_quill) package to add support for dealing with conversion to/from html
It uses [vsc_quill_delta_to_html](https://pub.dev/packages/vsc_quill_delta_to_html) package to convert the the delta to HTML
## Features
```markdown
- Easy to use
- Support with Flutter Quill package
```
## Getting started
This will be updated soon.
## Usage
Take a look at the example of the repo, This will be updated soon.
## Additional information
This will be updated soon.

@ -0,0 +1,36 @@
include: package:flutter_lints/flutter.yaml
analyzer:
errors:
undefined_prefixed_name: ignore
unsafe_html: ignore
linter:
rules:
always_declare_return_types: true
always_put_required_named_parameters_first: true
annotate_overrides: true
avoid_empty_else: true
avoid_escaping_inner_quotes: true
avoid_print: true
avoid_redundant_argument_values: true
avoid_types_on_closure_parameters: true
avoid_void_async: true
cascade_invocations: true
directives_ordering: true
omit_local_variable_types: true
prefer_const_constructors: true
prefer_const_constructors_in_immutables: true
prefer_const_declarations: true
prefer_final_fields: true
prefer_final_in_for_each: true
prefer_final_locals: true
prefer_initializing_formals: true
prefer_int_literals: true
prefer_interpolation_to_compose_strings: true
prefer_relative_imports: true
prefer_single_quotes: true
sort_constructors_first: true
sort_unnamed_constructors_first: true
unnecessary_lambdas: true
unnecessary_parenthesis: true
unnecessary_string_interpolations: true

@ -0,0 +1 @@
Subproject commit 22e49a1abe72894f6666baedcc00fb89f13d2c4a

@ -0,0 +1,132 @@
library flutter_quill_html;
import 'dart:convert' show jsonDecode;
import 'package:delta_markdown/delta_markdown.dart' show markdownToDelta;
import 'package:flutter/foundation.dart';
import 'package:flutter_quill/flutter_quill.dart' show Delta;
// ignore: depend_on_referenced_packages
import 'package:html/dom.dart' as html_dom;
// ignore: depend_on_referenced_packages
import 'package:html/parser.dart' as html_parse;
import 'package:html2md/html2md.dart' as html2md;
import 'package:vsc_quill_delta_to_html/vsc_quill_delta_to_html.dart'
as conventer show ConverterOptions, QuillDeltaToHtmlConverter;
typedef ConverterOptions = conventer.ConverterOptions;
extension DeltaHtmlExt on Delta {
String toHtml({ConverterOptions? options}) {
final html = conventer.QuillDeltaToHtmlConverter(
List.castFrom(toJson()),
options,
).convert();
return html;
}
static Delta fromHtml(String html) {
return Delta.fromJson(
jsonDecode(
markdownToDelta(
html2md.convert(html),
),
),
);
}
}
// From https://github.com/singerdmx/flutter-quill/issues/1100#issuecomment-1681274676
@immutable
class HtmlToDeltaConverter {
static const _collorPattern = r'color: rgb\((\d+), (\d+), (\d+)\);';
static Delta _parseInlineStyles(html_dom.Element element) {
var delta = Delta();
for (final node in element.nodes) {
final attributes = _parseElementStyles(element);
if (node is html_dom.Text) {
delta.insert(node.text, attributes);
} else if (node is html_dom.Element && node.localName == 'img') {
final src = node.attributes['src'];
if (src != null) {
delta.insert({'image': src});
}
} else if (node is html_dom.Element) {
delta = delta.concat(_parseInlineStyles(node));
}
}
return delta;
}
static Map<String, dynamic> _parseElementStyles(html_dom.Element element) {
final attributes = <String, dynamic>{};
if (element.localName == 'strong') attributes['bold'] = true;
if (element.localName == 'em') attributes['italic'] = true;
if (element.localName == 'u') attributes['underline'] = true;
if (element.localName == 'del') attributes['strike'] = true;
final style = element.attributes['style'];
if (style != null) {
final colorValue = _parseColorFromStyle(style);
if (colorValue != null) attributes['color'] = colorValue;
final bgColorValue = _parseBackgroundColorFromStyle(style);
if (bgColorValue != null) attributes['background'] = bgColorValue;
}
return attributes;
}
static String? _parseColorFromStyle(String style) {
if (RegExp(r'(^|\s)color:(\s|$)').hasMatch(style)) {
return _parseRgbColorFromMatch(RegExp(_collorPattern).firstMatch(style));
}
return null;
}
static String? _parseBackgroundColorFromStyle(String style) {
if (RegExp(r'(^|\s)background-color:(\s|$)').hasMatch(style)) {
return _parseRgbColorFromMatch(RegExp(_collorPattern).firstMatch(style));
}
return null;
}
static String? _parseRgbColorFromMatch(RegExpMatch? colorMatch) {
if (colorMatch != null) {
try {
final red = int.parse(colorMatch.group(1)!);
final green = int.parse(colorMatch.group(2)!);
final blue = int.parse(colorMatch.group(3)!);
return '#${red.toRadixString(16).padLeft(2, '0')}${green.toRadixString(16).padLeft(2, '0')}${blue.toRadixString(16).padLeft(2, '0')}';
} catch (e) {
// debugPrintStack(label: e.toString());
}
}
return null;
}
static Delta htmlToDelta(String html) {
final document = html_parse.parse(html);
var delta = Delta();
for (final node in document.body?.nodes ?? []) {
if (node is html_dom.Element) {
switch (node.localName) {
case 'p':
delta = delta.concat(_parseInlineStyles(node))..insert('\n');
break;
case 'br':
delta.insert('\n');
break;
}
}
}
return html.isNotEmpty ? delta : Delta()
..insert('\n');
}
}

@ -0,0 +1,38 @@
name: flutter_quill_html
description: A extension for flutter_quill package to add support for dealing with conversion to/from html
version: 0.0.1-experimental.1
homepage: https://github.com/singerdmx/flutter-quill/tree/master/packages/flutter_quill_html
repository: https://github.com/singerdmx/flutter-quill/tree/master/packages/flutter_quill_html
topics:
- ui
- widgets
- widget
- rich-text-editor
- quill
environment:
sdk: '>=3.1.5 <4.0.0'
flutter: ">=1.17.0"
dependencies:
flutter:
sdk: flutter
flutter_quill: ^8.5.1
vsc_quill_delta_to_html: ^1.0.3
html2md: ^1.3.1
delta_markdown:
path: ./delta_markdown
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^3.0.1
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
uses-material-design: true

@ -0,0 +1,3 @@
dependency_overrides:
flutter_quill:
path: ../../

@ -0,0 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
void main() {
test('No tests for now', () {
expect(true, true);
});
}

@ -19,4 +19,9 @@ rm flutter_quill_test/pubspec_overrides.yaml
echo ""
echo "Disable local development for all the other packages..."
rm packages/flutter_quill_html/pubspec_overrides.yaml
echo ""
echo "Local development for all libraries has been disabled, please 'flutter pub get' for each one of them"

@ -19,4 +19,9 @@ cp flutter_quill_test/pubspec_overrides.yaml.g flutter_quill_test/pubspec_overri
echo ""
echo "Enable local development for all the other packages..."
cp packages/flutter_quill_html/pubspec_overrides.yaml.g packages/flutter_quill_html/pubspec_overrides.yaml
echo ""
echo "Local development for all libraries has been enabled, please 'flutter pub get' for each one of them"
Loading…
Cancel
Save