This commit is contained in:
relikd
2025-12-04 15:13:22 +01:00
commit f8545f5c77
22 changed files with 3105 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="PreviewViewController" customModuleProvider="target">
<connections>
<outlet property="view" destination="c22-O7-iKe" id="NRM-P4-wb6"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="c22-O7-iKe" userLabel="Preview View">
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</customView>
</objects>
</document>

24
QLPreview/Info.plist Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>QLIsDataBasedPreview</key>
<false/>
<key>QLSupportedContentTypes</key>
<array>
<string>net.daringfireball.markdown</string>
</array>
<key>QLSupportsSearchableItems</key>
<false/>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.quicklook.preview</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).PreviewViewController</string>
</dict>
</dict>
</plist>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.temporary-exception.files.absolute-path.read-only</key>
<array>
<string>/</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,88 @@
import Cocoa
import Quartz // QLPreviewingController
import WebKit // WebView
import Markdown // Document, HTMLFormatter
//import os // OSLog
//
//private let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "preview-plugin")
extension URL {
/// Folder where user can mofifications to html template
static let UserModDir: URL? =
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
/// Returns `true` if file or folder exists.
@inlinable func exists() -> Bool {
FileManager.default.fileExists(atPath: self.path)
}
}
class PreviewViewController: NSViewController, QLPreviewingController, WKNavigationDelegate {
var url: URL? = nil
var html: String? = nil
override var nibName: NSNib.Name? {
return NSNib.Name("PreviewViewController")
}
/// Load resource file either from user documents dir (if exists) or app bundle (default).
func bundleFile(filename: String, ext: String) throws -> URL {
if let userFile = URL.UserModDir?.appendingPathComponent(filename + "." + ext, isDirectory: false), userFile.exists() {
return userFile
}
return Bundle.main.url(forResource: filename, withExtension: ext)!
}
func preparePreviewOfFile(at url: URL) async throws {
let cssUrl = try bundleFile(filename: "markdown", ext: "css")
let md = try Document(parsing: url)
self.url = url
self.html = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="\(cssUrl)" />
</head>
<body class="markdown-body">
\(HTMLFormatter.format(md))
</body>
</html>
"""
// write debug output
//try? html!.write(to: URL.UserModDir!.appendingPathComponent("debug.html", isDirectory: false), atomically: true, encoding: .utf8)
// create web view UI
let web = WKWebView(frame: self.view.bounds)
web.navigationDelegate = self
web.autoresizingMask = [.width, .height]
self.view.addSubview(web)
// allow read access to all files under root "/"
let emtpy = Bundle.main.url(forResource: "empty", withExtension: "txt")!
web.loadFileURL(emtpy, allowingReadAccessTo: URL(string: "file:///")!)
// loadHTMLString must wait until previous request is fully loaded
// see delegate method below
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
if webView.url?.lastPathComponent == "empty.txt" {
webView.loadHTMLString(html!, baseURL: url)
html = nil // free up memory
}
}
// this should open links in external browser but it doesnt
// func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping @MainActor (WKNavigationActionPolicy) -> Void) {
// if navigationAction.navigationType == .linkActivated,
// let url = navigationAction.request.url {
// os_log(.debug, log: log, "open url %{public}@", String(describing: url))
// NSWorkspace.shared.open(url)
// decisionHandler(.cancel)
// } else {
// decisionHandler(.allow)
// }
// }
}