import 'dart:io'; import 'package:dartboard_resume/annotation_manager.dart'; import 'package:dartboard_resume/models/dartboard_data.dart'; import 'package:dartboard_resume/models/dartboard_misc.dart'; import 'package:dartboard_resume/models/experience.dart'; import 'package:dartboard_resume/models/theme.dart'; import 'package:dartboard_resume/widgets/dartboard_misc_entry.dart'; import 'package:dartboard_resume/widgets/experience_entry.dart'; import 'package:dartboard_resume/widgets/footer.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart'; import 'package:toml/toml.dart'; int? lastDartboardHash; Future renderPdf(String tomlFilePath, {bool force = false}) async { try { final start = DateTime.now().microsecondsSinceEpoch; final dartboardData = DartboardData.fromToml(tomlFilePath); if (lastDartboardHash == dartboardData.hashCode && !force) { return; } lastDartboardHash = dartboardData.hashCode; stdout.writeln("Detected change:\nRendering with new dartboard data: $lastDartboardHash"); final pdfFuture = Document()..addPage(_generatePdfPage(dartboardData: dartboardData, renderNs: 0)); await pdfFuture.save(); final renderNs = DateTime.now().microsecondsSinceEpoch - start; final pdf = Document(); pdf.addPage(_generatePdfPage(dartboardData: dartboardData, renderNs: renderNs)); final file = File("example.pdf"); final bytes = await pdf.save(); stdout.writeln('New pdf file saved.'); file.writeAsBytesSync(bytes); AnnotationManager().reset(); } catch (e, st) { stderr.writeln('Encountered error: $e'); stderr.writeln(st); try { stderr.writeln('Current toml map:\n${TomlDocument.loadSync(tomlFilePath).toMap()}'); } catch (_) { stderr.writeln('Cannot display current toml map'); } } } Page _generatePdfPage({required DartboardData dartboardData, required int renderNs}) { AnnotationManager().style = dartboardData.defaultTextStyle; final List groupedExperienceList = dartboardData.groupedExperiences.entries.map( (entry) { final String subsection = entry.key; final List experiences = entry.value; return Column( children: [ Row( children: [ Text( subsection, style: dartboardData.subheaderTextStyle .merge(const TextStyle(fontSize: 18)) .apply(color: const PdfColorGrey(0.2)), ), ], ), Row( children: [ Container(height: 2, width: 200, color: const PdfColorGrey(0.7)), ], ), SizedBox(height: 3), ...experiences.map( (Experience exp) => ExperienceEntry(dartboardData: dartboardData, exp: exp), ), ], ); }, ).toList(); final List groupedMiscList = dartboardData.groupedMisc.entries.map((entry) { final String subsection = entry.key; final List miscs = entry.value; return Column( children: [ Row( children: [ Text( subsection, style: dartboardData.subheaderTextStyle .merge(const TextStyle(fontSize: 18)) .apply(color: const PdfColorGrey(0.2)), ), ], ), Row( children: [ Container(height: 2, width: 200, color: const PdfColorGrey(0.7)), ], ), SizedBox(height: 3), ...miscs.map( (DartboardMisc misc) => DartboardMiscEntry(dartboardData: dartboardData, misc: misc), ), ], ); }).toList(); return Page( pageTheme: PageTheme( buildBackground: (_) => Container(color: dartboardData.backgroundColor), pageFormat: PdfPageFormat.standard, margin: EdgeInsets.zero, ), build: (Context context) { return FullPage( ignoreMargins: true, child: Padding( padding: const EdgeInsets.all(DocumentTheme.cm * 2), child: Column( children: [ if (dartboardData.imagePath == null) Center( child: Column( children: [ Text(dartboardData.fullName, style: dartboardData.headerTextStyle), if (dartboardData.phoneNumber != null) Text(dartboardData.phoneNumber!, style: dartboardData.headerTextStyle), if (dartboardData.email != null) Text(dartboardData.email!, style: dartboardData.headerTextStyle), ], ), ) else SizedBox( height: 100, width: double.infinity, child: Stack( children: [ if (dartboardData.imagePath != null) Positioned( left: 0, child: Container( height: 100, width: 100, decoration: BoxDecoration( shape: BoxShape.circle, image: DecorationImage( fit: BoxFit.contain, image: MemoryImage( File(dartboardData.imagePath!).readAsBytesSync(), ), ), ), ), ), Center( child: Column( children: [ Text(dartboardData.fullName, style: dartboardData.headerTextStyle), if (dartboardData.phoneNumber != null) Text(dartboardData.phoneNumber!, style: dartboardData.headerTextStyle), if (dartboardData.email != null) Text(dartboardData.email!, style: dartboardData.headerTextStyle), ], ), ), ], ), ), ...groupedExperienceList, ...groupedMiscList, // this is quirky and gets evaluated before the actual footnotes get added up, so the original adding is done in the prerender ...AnnotationManager().footnotes, DartboardFooter(dartboardData: dartboardData, renderNs: renderNs), ], // ), ), ), ); }, ); }