From bf38ca14420a42be54412a6eaf3fbe11f6f43c7b Mon Sep 17 00:00:00 2001 From: relikd Date: Thu, 16 Jan 2020 15:47:37 +0100 Subject: [PATCH] Proper qlmanage debugging + dark mode with media query instead of NSAppearance --- QLOPML.xcodeproj/project.pbxproj | 20 ++++--- .../xcshareddata/xcschemes/QLOPML.xcscheme | 26 +++++++-- QLOPML/GeneratePreviewForURL.c | 30 +++++++++++ QLOPML/opml-lib.h | 6 +++ .../{GeneratePreviewForURL.m => opml-lib.m} | 53 ++++--------------- QLOPML/style.css | 13 ++--- sample.opml | 39 ++++++++++++++ 7 files changed, 127 insertions(+), 60 deletions(-) create mode 100644 QLOPML/GeneratePreviewForURL.c create mode 100644 QLOPML/opml-lib.h rename QLOPML/{GeneratePreviewForURL.m => opml-lib.m} (59%) create mode 100644 sample.opml diff --git a/QLOPML.xcodeproj/project.pbxproj b/QLOPML.xcodeproj/project.pbxproj index 3245d27..08b8927 100644 --- a/QLOPML.xcodeproj/project.pbxproj +++ b/QLOPML.xcodeproj/project.pbxproj @@ -8,18 +8,23 @@ /* Begin PBXBuildFile section */ 540A649C22EE78B200470937 /* GenerateThumbnailForURL.c in Sources */ = {isa = PBXBuildFile; fileRef = 540A649B22EE78B200470937 /* GenerateThumbnailForURL.c */; }; - 540A649E22EE78B200470937 /* GeneratePreviewForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 540A649D22EE78B200470937 /* GeneratePreviewForURL.m */; }; + 540A649E22EE78B200470937 /* GeneratePreviewForURL.c in Sources */ = {isa = PBXBuildFile; fileRef = 540A649D22EE78B200470937 /* GeneratePreviewForURL.c */; }; 540A64A022EE78B200470937 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 540A649F22EE78B200470937 /* main.c */; }; 541EF8B322EEFBEA00C415AA /* style.css in Resources */ = {isa = PBXBuildFile; fileRef = 541EF8B122EEFB2300C415AA /* style.css */; }; + 54BFFC1123D09E7300012FBB /* opml-lib.h in Headers */ = {isa = PBXBuildFile; fileRef = 54BFFC0F23D09E7300012FBB /* opml-lib.h */; }; + 54BFFC1223D09E7300012FBB /* opml-lib.m in Sources */ = {isa = PBXBuildFile; fileRef = 54BFFC1023D09E7300012FBB /* opml-lib.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 540A649822EE78B200470937 /* QLOPML.qlgenerator */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QLOPML.qlgenerator; sourceTree = BUILT_PRODUCTS_DIR; }; 540A649B22EE78B200470937 /* GenerateThumbnailForURL.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = GenerateThumbnailForURL.c; sourceTree = ""; }; - 540A649D22EE78B200470937 /* GeneratePreviewForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GeneratePreviewForURL.m; sourceTree = ""; }; + 540A649D22EE78B200470937 /* GeneratePreviewForURL.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = GeneratePreviewForURL.c; sourceTree = ""; }; 540A649F22EE78B200470937 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 540A64A122EE78B200470937 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 541EF8B122EEFB2300C415AA /* style.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = style.css; sourceTree = ""; }; + 54BFFC0423D0988A00012FBB /* sample.opml */ = {isa = PBXFileReference; lastKnownFileType = file; path = sample.opml; sourceTree = SOURCE_ROOT; }; + 54BFFC0F23D09E7300012FBB /* opml-lib.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "opml-lib.h"; sourceTree = ""; }; + 54BFFC1023D09E7300012FBB /* opml-lib.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "opml-lib.m"; sourceTree = ""; }; 54FB05D22305C8F400A088AD /* QLOPML.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = QLOPML.entitlements; sourceTree = ""; }; /* End PBXFileReference section */ @@ -54,11 +59,14 @@ isa = PBXGroup; children = ( 54FB05D22305C8F400A088AD /* QLOPML.entitlements */, + 54BFFC0F23D09E7300012FBB /* opml-lib.h */, + 54BFFC1023D09E7300012FBB /* opml-lib.m */, 540A649B22EE78B200470937 /* GenerateThumbnailForURL.c */, - 540A649D22EE78B200470937 /* GeneratePreviewForURL.m */, + 540A649D22EE78B200470937 /* GeneratePreviewForURL.c */, 540A649F22EE78B200470937 /* main.c */, 540A64A122EE78B200470937 /* Info.plist */, 541EF8B122EEFB2300C415AA /* style.css */, + 54BFFC0423D0988A00012FBB /* sample.opml */, ); path = QLOPML; sourceTree = ""; @@ -70,6 +78,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 54BFFC1123D09E7300012FBB /* opml-lib.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -150,7 +159,8 @@ buildActionMask = 2147483647; files = ( 540A649C22EE78B200470937 /* GenerateThumbnailForURL.c in Sources */, - 540A649E22EE78B200470937 /* GeneratePreviewForURL.m in Sources */, + 54BFFC1223D09E7300012FBB /* opml-lib.m in Sources */, + 540A649E22EE78B200470937 /* GeneratePreviewForURL.c in Sources */, 540A64A022EE78B200470937 /* main.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -281,7 +291,6 @@ isa = XCBuildConfiguration; buildSettings = { INFOPLIST_FILE = QLOPML/Info.plist; - INSTALL_PATH = /Library/QuickLook; PRODUCT_BUNDLE_IDENTIFIER = de.relikd.QLOPML; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = qlgenerator; @@ -292,7 +301,6 @@ isa = XCBuildConfiguration; buildSettings = { INFOPLIST_FILE = QLOPML/Info.plist; - INSTALL_PATH = /Library/QuickLook; PRODUCT_BUNDLE_IDENTIFIER = de.relikd.QLOPML; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = qlgenerator; diff --git a/QLOPML.xcodeproj/xcshareddata/xcschemes/QLOPML.xcscheme b/QLOPML.xcodeproj/xcshareddata/xcschemes/QLOPML.xcscheme index cc36ec5..7811395 100644 --- a/QLOPML.xcodeproj/xcshareddata/xcschemes/QLOPML.xcscheme +++ b/QLOPML.xcodeproj/xcshareddata/xcschemes/QLOPML.xcscheme @@ -29,8 +29,6 @@ shouldUseLaunchSchemeArgsEnv = "YES"> - - + + - - + + + + + + + + + + +#include +#include +#include "opml-lib.h" + +OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); +void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); + +/* ----------------------------------------------------------------------------- + Generate a preview for file + + This function's job is to create preview for designated file + ----------------------------------------------------------------------------- */ + +OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) +{ + // qlmanage -r && qlmanage -p test.opml -o tmp/ && edit tmp/test.opml.qlpreview/Preview.html + CFBundleRef bundle = QLPreviewRequestGetGeneratorBundle(preview); + CFDataRef data = renderOPML(url, bundle); + if (data) { + QLPreviewRequestSetDataRepresentation(preview, data, kUTTypeHTML, NULL); + CFRelease(data); + } + return noErr; +} + +void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview) +{ + // Implement only if supported +} diff --git a/QLOPML/opml-lib.h b/QLOPML/opml-lib.h new file mode 100644 index 0000000..207bba5 --- /dev/null +++ b/QLOPML/opml-lib.h @@ -0,0 +1,6 @@ +#ifndef opml_lib_h +#define opml_lib_h + +CFDataRef renderOPML(CFURLRef url, CFBundleRef bundle); + +#endif /* opml_lib_h */ diff --git a/QLOPML/GeneratePreviewForURL.m b/QLOPML/opml-lib.m similarity index 59% rename from QLOPML/GeneratePreviewForURL.m rename to QLOPML/opml-lib.m index 409a043..a5db3cc 100644 --- a/QLOPML/GeneratePreviewForURL.m +++ b/QLOPML/opml-lib.m @@ -1,36 +1,8 @@ -#include -#include -#include -#include -#include - -NSData* renderOPML(NSURL* url, CFBundleRef bundle); - -OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options); -void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview); - -/* ----------------------------------------------------------------------------- - Generate a preview for file - - This function's job is to create preview for designated file - ----------------------------------------------------------------------------- */ - -OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options) -{ - // qlmanage -r && qlmanage -p test.opml -o tmp/ && edit tmp/test.opml.qlpreview/Preview.html - CFBundleRef bundle = QLPreviewRequestGetGeneratorBundle(preview); - CFDataRef data = CFBridgingRetain(renderOPML((__bridge NSURL*)url, bundle)); - if (data) { - QLPreviewRequestSetDataRepresentation(preview, data, kUTTypeHTML, NULL); - } - return noErr; -} - -void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview) -{ - // Implement only if supported -} - +//#import +//#import +//#import +#import +#import // --------------------------------------------------------------- // | @@ -52,7 +24,7 @@ void attribute(NSXMLElement *parent, NSString *key, NSString *value) { NSXMLElement* section(NSString *title, NSString *container, NSXMLElement *parent) { make(@"h3", title, parent); NSXMLElement *div = make(container, nil, parent); - attribute(div, @"class", @"first"); + attribute(div, @"class", @"section"); return div; } @@ -94,9 +66,9 @@ void appendNode(NSXMLElement *child, NSXMLElement *parent) { } } -NSData* renderOPML(NSURL* url, CFBundleRef bundle) { +CFDataRef renderOPML(CFURLRef url, CFBundleRef bundle) { NSError *err; - NSXMLDocument *doc = [[NSXMLDocument alloc] initWithContentsOfURL:url options:0 error:&err]; + NSXMLDocument *doc = [[NSXMLDocument alloc] initWithContentsOfURL:(__bridge NSURL*)url options:0 error:&err]; if (err || !doc) { printf("ERROR: %s\n", err.description.UTF8String); return nil; @@ -112,16 +84,9 @@ NSData* renderOPML(NSURL* url, CFBundleRef bundle) { NSXMLElement *body = make(@"body", nil, html); - NSString *appearance = @"light"; - if (@available(macOS 10.14, *)) { - if ([NSAppearance.currentAppearance.name isEqualToString:NSAppearanceNameDarkAqua]) - appearance = @"dark"; - } - attribute(body, @"class", appearance); - for (NSXMLElement *child in doc.children) { appendNode(child, body); } NSXMLDocument *xml = [NSXMLDocument documentWithRootElement:html]; - return [xml XMLDataWithOptions:NSXMLNodePrettyPrint | NSXMLNodeCompactEmptyElement]; + return CFBridgingRetain([xml XMLDataWithOptions:NSXMLNodePrettyPrint | NSXMLNodeCompactEmptyElement]); } diff --git a/QLOPML/style.css b/QLOPML/style.css index e6dacdd..75da287 100644 --- a/QLOPML/style.css +++ b/QLOPML/style.css @@ -1,11 +1,12 @@ * { font-family: Courier; } -body { padding: 30px; } +body { padding: 30px; background-color: #AAA; color: black; } dd, li, hr { font-weight: bold; line-height: 1.5em; } ul { list-style-type: none; padding-bottom: 1em; } a { font-size: 0.75em; color: #FBA43A; } -.light { background-color: #AAA; color: black; } -.dark { background-color: #555; color: white; } -.first { padding: 1em 1.5em; border-radius: 7px; } -.light .first { background-color: #EEE; } -.dark .first { background-color: #222; } +.section { padding: 1em 1.5em; border-radius: 7px; background-color: #EEE; } + +@media (prefers-color-scheme: dark) { +body { background-color: #555; color: white; } +.section { background-color: #222; } +} diff --git a/sample.opml b/sample.opml new file mode 100644 index 0000000..4ac8484 --- /dev/null +++ b/sample.opml @@ -0,0 +1,39 @@ + + + + Sample OPML file for RSSReader + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +