Sources/OrgstarMobile/ExportMenu.swift
62 lines · 2440 bytes
1#if os(iOS)
2import CoreTransferable
3import OrgApp
4import OrgCore
5import SwiftUI
6import UniformTypeIdentifiers
7
8/// A file exported as HTML or Markdown, written when the share sheet takes it.
9struct OrgExport: Transferable {
10 enum Format { case html, markdown }
11
12 let text: String
13 let path: String
14 let format: Format
15 let settings: OrgSettings
16
17 var fileName: String {
18 let base = ((path as NSString).lastPathComponent as NSString).deletingPathExtension
19 return base + (format == .html ? ".html" : ".md")
20 }
21
22 static var transferRepresentation: some TransferRepresentation {
23 FileRepresentation(exportedContentType: .html) { export in
24 try export.write()
25 }
26 .exportingCondition { $0.format == .html }
27 FileRepresentation(exportedContentType: UTType(filenameExtension: "md") ?? .plainText) { export in
28 try export.write()
29 }
30 .exportingCondition { $0.format == .markdown }
31 }
32
33 private func write() throws -> SentTransferredFile {
34 let base = ((path as NSString).lastPathComponent as NSString).deletingPathExtension
35 let settings = settings.resolvingSetupFiles(in: text, path: path, read: OrgSettings.readFile)
36 let content = switch format {
37 case .html: HTMLExport.page(text, fallbackTitle: base, settings: settings, path: path)
38 case .markdown: MarkdownExport.document(text, settings: settings, path: path)
39 }
40 let folder = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
41 try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
42 let url = folder.appendingPathComponent(fileName)
43 try content.write(to: url, atomically: true, encoding: .utf8)
44 return SentTransferredFile(url)
45 }
46}
47
48/// Sharing the file as HTML or Markdown: to another app, or saved with Save to Files.
49struct ExportMenu: View {
50 let path: String
51 let text: String
52
53 var body: some View {
54 Menu("Export", systemImage: "square.and.arrow.up") {
55 ForEach([(OrgExport.Format.html, "HTML"), (.markdown, "Markdown")], id: \.1) { format, name in
56 let export = OrgExport(text: text, path: path, format: format, settings: OrgPreferences.orgSettings())
57 ShareLink(item: export, preview: SharePreview(export.fileName)) { Text(name) }
58 }
59 }
60 }
61}
62#endif