diff --git a/quill_html_converter/lib/quill_html_converter.dart b/quill_html_converter/lib/quill_html_converter.dart
index 6c685f75..e5206c56 100644
--- a/quill_html_converter/lib/quill_html_converter.dart
+++ b/quill_html_converter/lib/quill_html_converter.dart
@@ -1,8 +1,7 @@
library quill_html_converter;
import 'package:dart_quill_delta/dart_quill_delta.dart';
-import 'package:vsc_quill_delta_to_html/vsc_quill_delta_to_html.dart'
- as converter
+import 'package:vsc_quill_delta_to_html/vsc_quill_delta_to_html.dart' as converter
show
ConverterOptions,
QuillDeltaToHtmlConverter,
@@ -29,67 +28,104 @@ extension DeltaHtmlExt on Delta {
final json = toJson();
final html = converter.QuillDeltaToHtmlConverter(
List.castFrom(json),
- options ??
- ConverterOptions(
- orderedListTag: 'ol',
- bulletListTag: 'ul',
- multiLineBlockquote: true,
- multiLineHeader: true,
- multiLineCodeblock: true,
- multiLineParagraph: true,
- multiLineCustomBlock: true,
- sanitizerOptions: converter.OpAttributeSanitizerOptions(
- allow8DigitHexColors: true),
- converterOptions: converter.OpConverterOptions(
- customCssStyles: (op) {
- ///if found line-height apply this as a inline style
- if (op.attributes['line-height'] != null) {
- return ['line-height: ${op.attributes['line-height']}px'];
- }
- //here is where us pass the necessary
- //code to validate if our attributes exist in [DeltaInsertOp]
- //and return the necessary html style
- if (op.isImage()) {
- // Fit images within restricted parent width.
- return ['max-width: 100%', 'object-fit: contain'];
- }
- if (op.isBlockquote()) {
- return ['border-left: 4px solid #ccc', 'padding-left: 16px'];
- }
- return null;
- },
- inlineStylesFlag: true, //This let inlineStyles work
- inlineStyles: converter.InlineStyles(
- {
- 'font': converter.InlineStyleType(
- fn: (value, _) =>
- converter.defaultInlineFonts[value] ??
- 'font-family: $value'),
- 'size': converter.InlineStyleType(fn: (value, _) {
- //default sizes
- if (value == 'small') return 'font-size: 0.75em';
- if (value == 'large') return 'font-size: 1.5em';
- if (value == 'huge') return 'font-size: 2.5em';
- //accept any int or double type size
- return 'font-size: ${value}px';
- }),
- 'indent': converter.InlineStyleType(fn: (value, op) {
- final indentSize =
- (double.tryParse(value) ?? double.nan) * 3;
- final side =
- op.attributes['direction'] == 'rtl' ? 'right' : 'left';
- return 'padding-$side:${indentSize}em';
- }),
- 'list': converter.InlineStyleType(map: {
- 'checked': "list-style-type:'\\2611';padding-left: 0.5em;",
- 'unchecked':
- "list-style-type:'\\2610';padding-left: 0.5em;",
- }),
- },
- ),
- ),
- ),
+ options ?? _defaultConverterOptions,
).convert();
return html;
}
}
+
+/// Configuration options for converting Quill Delta to HTML.
+/// This includes various settings for how different elements and styles should be handled.
+final _defaultConverterOptions = ConverterOptions(
+ // Tag to be used for ordered lists
+ orderedListTag: 'ol',
+
+ // Tag to be used for bullet lists
+ bulletListTag: 'ul',
+
+ // Enable multi-line blockquote conversion
+ multiLineBlockquote: true,
+
+ // Enable multi-line header conversion
+ multiLineHeader: true,
+
+ // Enable multi-line code block conversion
+ multiLineCodeblock: true,
+
+ // Enable multi-line paragraph conversion
+ multiLineParagraph: true,
+
+ // Enable multi-line custom block conversion
+ multiLineCustomBlock: true,
+
+ // Options for sanitizing attributes
+ sanitizerOptions: converter.OpAttributeSanitizerOptions(
+ // Allow 8-digit hex colors in styles
+ allow8DigitHexColors: true,
+ ),
+
+ // This handle specific styles and attributes
+ converterOptions: converter.OpConverterOptions(
+ customCssStyles: (op) {
+ // Validate if our attributes exist in [DeltaInsertOp]
+ // and return the necessary HTML style
+ // These lists of attributes, are passed as inline styles
+ //
+ // For example, if you have a delta like ->
+ // [ { "insert": "hello", "attributes": { "line-height": 1.5 }} ]
+ //
+ // Without the validation below to verify if exist line-height atribute in the Operation, it would be:
+ // hello
-> isn't created the attribute
+ //
+ // But, with this validation an implementation of the style will be:
+ // hello
+ if (op.attributes['line-height'] != null) {
+ return ['line-height: ${op.attributes['line-height']}px'];
+ }
+ if (op.isImage()) {
+ // Fit images within restricted parent width
+ return ['max-width: 100%', 'object-fit: contain'];
+ }
+ if (op.isBlockquote()) {
+ // Style for blockquotes
+ return ['border-left: 4px solid #ccc', 'padding-left: 16px'];
+ }
+ return null;
+ },
+ // Enable inline styles
+ inlineStylesFlag: true,
+ inlineStyles: converter.InlineStyles(
+ {
+ 'font': converter.InlineStyleType(
+ fn: (value, _) => converter.defaultInlineFonts[value] ?? 'font-family: $value',
+ ),
+ 'size': converter.InlineStyleType(
+ fn: (value, _) {
+ // Default sizes
+ if (value == 'small') return 'font-size: 0.75em';
+ if (value == 'large') return 'font-size: 1.5em';
+ if (value == 'huge') return 'font-size: 2.5em';
+ // Accept any int or double type size
+ return 'font-size: ${value}px';
+ },
+ ),
+ 'indent': converter.InlineStyleType(
+ fn: (value, op) {
+ // Calculate indent size based on the value
+ final indentSize = (double.tryParse(value) ?? double.nan) * 3;
+ // Determine side for padding based on text direction
+ final side = op.attributes['direction'] == 'rtl' ? 'right' : 'left';
+ return 'padding-$side:${indentSize}em';
+ },
+ ),
+ 'list': converter.InlineStyleType(
+ map: {
+ // Styles for checked and unchecked list items
+ 'checked': "list-style-type:'\\2611';padding-left: 0.5em;",
+ 'unchecked': "list-style-type:'\\2610';padding-left: 0.5em;",
+ },
+ ),
+ },
+ ),
+ ),
+);