krz/orgstar

A native macOS editor for org-mode files. editor org-mode swift

Sources/OrgstarMobile/ExportMenu.swift

b98a6509c5ae75e5172dd333d1b6105fd6ceee0e
orgstar/Sources/OrgstarMobile/ExportMenu.swift history · blame · raw

62 lines · 2440 bytes

4 symbols in this file
 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