feat: export document to PDF (#695)

* feat: create initial parser for PDF format

* chore: add comments to explain code.

* chore: commit missing file

* feat: init commit for pdf parser

* chore: bind dependancy to git repo fork for fixes

* feat: get basic text from parser

* feat: get textstyle working with various texts

* fix: ensure formatting(bold, italics) doesnt break paragraphs

- Remove additional comments.

* chore: remove htmltopdfwidgets dependancy

* chore: clean up redundant code and add helper functions

* chore: update example files to include pdf option for export

* fix: remove html exportFileType

* feat: add in image support

* feat: add image support for network & local image

* feat: enable table support

* fix: enable tables in pdf parser

- Tables are enabled but lists within a table are not working yet.
- There is also the case of strikethrough not working, probably it didnt get rendered as a tag.
- Cleaned up example.dart

* chore: clean up comments in files & unused imports.

* chore: remove unused file.

---------

Co-authored-by: Lucas.Xu <lucas.xu@appflowy.io>
This commit is contained in:
Sean Riley Hawkins 2024-07-04 05:57:43 +02:00 • committed by GitHub
commit f6ee2fc02c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -18,12 +18,13 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:printing/printing.dart';
import 'package:universal_html/html.dart' as html;
enum ExportFileType {
documentJson,
markdown,
html,
pdf,
delta,
}
@ -35,8 +36,8 @@ extension on ExportFileType {
return 'json';
case ExportFileType.markdown:
return 'md';
case ExportFileType.html:
return 'html';
case ExportFileType.pdf:
return 'pdf';
}
}
}
@ -145,7 +146,6 @@ class _HomePageState extends State<HomePage> {
final htmlString =
await rootBundle.loadString('assets/example.html');
final html = htmlToDocument(htmlString);
// final html = HTMLToNodesConverter(htmlString).toDocument();
final jsonString = Future<String>.value(
jsonEncode(
html.toJson(),
@ -250,6 +250,10 @@ class _HomePageState extends State<HomePage> {
_exportFile(_editorState, ExportFileType.markdown);
}),
_buildListTile(context, 'Export to PDF', () {
_exportFile(_editorState, ExportFileType.pdf);
}),
// Decoder Demo
_buildSeparator(context, 'Import From X Demo'),
_buildListTile(context, 'Import From Document JSON', () {
@ -339,7 +343,10 @@ class _HomePageState extends State<HomePage> {
case ExportFileType.markdown:
result = documentToMarkdown(editorState.document);
break;
case ExportFileType.html:
case ExportFileType.pdf:
result = documentToMarkdown(editorState.document);
break;
case ExportFileType.delta:
throw UnimplementedError();
}
@ -374,6 +381,17 @@ class _HomePageState extends State<HomePage> {
);
if (path != null) {
await File(path).writeAsString(result);
if (fileType == ExportFileType.pdf) {
final pdf = await PdfHTMLEncoder(
fontFallback: [
await PdfGoogleFonts.notoColorEmoji(),
await PdfGoogleFonts.notoColorEmojiRegular(),
],
).convert(result);
await File(path).writeAsBytes(await pdf.save());
}
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
@ -419,7 +437,7 @@ class _HomePageState extends State<HomePage> {
final document = quillDeltaEncoder.convert(delta);
jsonString = jsonEncode(document.toJson());
break;
case ExportFileType.html:
case ExportFileType.pdf:
throw UnimplementedError();
}