Skip to content

Commit

Permalink
fix attributes parsing and support for more attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
CatHood0 committed Jul 8, 2024
1 parent 47129d3 commit f00b0f3
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 21 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.2.1

* Feat: added support for align attribute (a different way of align the text, like: text-align)
* Fix: Line-height is not pasted as double

## 1.2.0

* Chore: removed flutter_quill dependency to use only required parts of it
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ This is a Dart package that converts HTML input into Quill Delta format, which i
Code Blocks
<pre>, <code>: Code blocks

Text Alignment
<p style="text-align:left|center|right|justify">: Paragraph alignment
Text Alignment, inline text align and direction
<p style="text-align:left|center|right|justify">: Paragraph style alignment
<p align="left|center|right|justify">: Paragraph alignment
<p dir="rtl">: Paragraph direction

Text attributes
<p style="line-height: 1.0;font-size: 12;font-family: Times New Roman;color:#ffffff">: Inline attributes
Expand All @@ -63,7 +65,7 @@ Add the dependency to your pubspec.yaml:

```yaml
dependencies:
flutter_quill_delta_from_html: ^1.2.0
flutter_quill_delta_from_html: ^1.2.1
```
Then, import the package and use it in your Flutter application:
Expand Down
38 changes: 29 additions & 9 deletions lib/parser/html_to_operation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,19 @@ class DefaultHtmlToOperations extends HtmlOperations {
Map<String, dynamic> inlineAttributes = {};
Map<String, dynamic> blockAttributes = {};
// Process the style attribute
if (attributes.containsKey('style')) {
final String style = element.attributes['style']!;
if (attributes.containsKey('style') || attributes.containsKey('align') || attributes.containsKey('dir')) {
final String style = attributes['style'] ?? '';
final String? styles2 = attributes['align'];
final String? styles3 = attributes['dir'];
final styleAttributes = parseStyleAttribute(style);
if (styleAttributes.containsKey('align')) {
final alignAttribute = parseStyleAttribute(styles2 ?? '');
final dirAttribute = parseStyleAttribute(styles3 ?? '');
styleAttributes.addAll({...alignAttribute, ...dirAttribute});
if (styleAttributes.containsKey('align') || styleAttributes.containsKey('direction')) {
blockAttributes['align'] = styleAttributes['align'];
blockAttributes['direction'] = styleAttributes['direction'];
styleAttributes.remove('align');
styleAttributes.remove('direction');
}
inlineAttributes.addAll(styleAttributes);
}
Expand All @@ -104,6 +111,7 @@ class DefaultHtmlToOperations extends HtmlOperations {
processNode(node, inlineAttributes, delta, addSpanAttrs: true, customBlocks: customBlocks);
}
if (blockAttributes.isNotEmpty) {
blockAttributes.removeWhere((key, value) => value == null);
delta.insert('\n', blockAttributes);
}

Expand All @@ -117,8 +125,8 @@ class DefaultHtmlToOperations extends HtmlOperations {
Map<String, dynamic> inlineAttributes = {};
// Process the style attribute
if (attributes.containsKey('style')) {
final String style = element.attributes['style'] ?? '';
final styleAttributes = parseStyleAttribute(style);
final String? style = attributes['style'];
final styleAttributes = parseStyleAttribute(style ?? '');
if (styleAttributes.containsKey('align')) {
styleAttributes.remove('align');
}
Expand Down Expand Up @@ -157,12 +165,21 @@ class DefaultHtmlToOperations extends HtmlOperations {
Map<String, dynamic> attributes = {};
Map<String, dynamic> blockAttributes = {};

if (element.attributes.containsKey('style')) {
final String style = element.attributes['style']!;
if (element.attributes.containsKey('style') ||
element.attributes.containsKey('align') ||
element.attributes.containsKey('dir')) {
final String style = element.attributes['style'] ?? '';
final String? styles2 = element.attributes['align'];
final String? styles3 = element.attributes['dir'];
final styleAttributes = parseStyleAttribute(style);
if (styleAttributes.containsKey('align')) {
final alignAttribute = parseStyleAttribute(styles2 ?? '');
final dirAttribute = parseStyleAttribute(styles3 ?? '');
styleAttributes.addAll({...alignAttribute, ...dirAttribute});
if (styleAttributes.containsKey('align') || styleAttributes.containsKey('direction')) {
blockAttributes['align'] = styleAttributes['align'];
blockAttributes['direction'] = styleAttributes['direction'];
styleAttributes.remove('align');
styleAttributes.remove('direction');
}
attributes.addAll(styleAttributes);
}
Expand All @@ -175,7 +192,10 @@ class DefaultHtmlToOperations extends HtmlOperations {
processNode(node, attributes, delta);
}
// Ensure a newline is added at the end of the header with the correct attributes
delta.insert('\n', blockAttributes);
if (blockAttributes.isNotEmpty) {
blockAttributes.removeWhere((key, value) => value == null);
delta.insert('\n', blockAttributes);
}
return delta.toList();
}

Expand Down
25 changes: 17 additions & 8 deletions lib/parser/html_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import 'custom_html_part.dart';

///verify if the tag is from a inline html tag attribute
bool isInline(String tag) {
return ["i", "em", "u", "ins", "s", "del", "b", "strong", "sub", "sup"]
.contains(tag);
return ["i", "em", "u", "ins", "s", "del", "b", "strong", "sub", "sup"].contains(tag);
}

///get all attributes from a tag, and parse to Delta attributes
Expand Down Expand Up @@ -35,17 +34,27 @@ Map<String, dynamic> parseStyleAttribute(String style) {
attributes['background'] = color;
break;
case 'font-size':
attributes['size'] = value;
attributes['size'] = value.replaceAll('px', '').replaceAll('em', '').replaceAll('vm', '');
break;
case 'font-family':
attributes['font'] = value;
break;
case 'line-height':
attributes['line-height'] = value;
attributes['line-height'] =
double.parse(value.replaceAll('px', '').replaceAll('em', '').replaceAll('vm', ''));
break;
default:
break;
}
} else {
switch (style) {
case 'justify' || 'center' || 'left' || 'right':
attributes['align'] = style;
case 'rtl':
attributes['direction'] = 'rtl';
default:
break;
}
}
}

Expand Down Expand Up @@ -74,8 +83,7 @@ void processNode(
if (customBlocks != null && customBlocks.isNotEmpty) {
for (var customBlock in customBlocks) {
if (customBlock.matches(node)) {
final operations =
customBlock.convert(node, currentAttributes: newAttributes);
final operations = customBlock.convert(node, currentAttributes: newAttributes);
operations.forEach((Operation op) {
delta.insert(op.data, op.attributes);
});
Expand All @@ -84,10 +92,10 @@ void processNode(
}
} else {
if (node.isSpan) {
final spanAttributes =
parseStyleAttribute(node.attributes['style'] ?? '');
final spanAttributes = parseStyleAttribute(node.attributes['style'] ?? '');
if (addSpanAttrs) {
newAttributes.remove('align');
newAttributes.remove('direction');
newAttributes.addAll({...spanAttributes});
}
}
Expand All @@ -99,6 +107,7 @@ void processNode(
}
if (node.isBreakLine) {
newAttributes.remove('align');
newAttributes.remove('direction');
delta.insert('\n', newAttributes);
}
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: flutter_quill_delta_from_html
description: "Convert easily HTML inputs content to Quill Delta format"
version: 1.2.0
version: 1.2.1
homepage:
repository: https://github.com/CatHood0/flutter_quill_delta_from_html/
issue_tracker: https://github.com/CatHood0/flutter_quill_delta_from_html/issues
Expand Down
40 changes: 40 additions & 0 deletions test/flutter_quill_delta_from_html_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,46 @@ void main() {
expect(delta, expectedDelta);
});

test('Paragraph alignment', () {
const html = '<p align="center">This is a paragraph example</p>';
final converter = HtmlToDelta();
final delta = converter.convert(html);

final expectedDelta = Delta()
..insert('This is a paragraph example')
..insert('\n', {"align": "center"})
..insert('\n');

expect(delta, expectedDelta);
});

test('Paragraph to RTL', () {
const html = '<p dir="rtl">This is a RTL paragraph example</p>';
final converter = HtmlToDelta();
final delta = converter.convert(html);

final expectedDelta = Delta()
..insert('This is a RTL paragraph example')
..insert('\n', {"direction": "rtl"})
..insert('\n');

expect(delta, expectedDelta);
});

test('Paragraph alignment RTL with inline styles', () {
const html =
'<p align="center" dir="rtl" style="line-height: 1.5px;font-size: 15px;font-family: Tinos">This is a paragraph example</p>';
final converter = HtmlToDelta();
final delta = converter.convert(html);

final expectedDelta = Delta()
..insert('This is a paragraph example', {"line-height": 1.5, "size": "15", "font": "Tinos"})
..insert('\n', {"align": "center", "direction": "rtl"})
..insert('\n');

expect(delta, expectedDelta);
});

test('Paragraph with spanned red text', () {
const html = '<p>This is a <span style="background-color:rgb(255,255,255)">red text</span></p>';
final converter = HtmlToDelta();
Expand Down

0 comments on commit f00b0f3

Please sign in to comment.