Revision: 16295
          http://sourceforge.net/p/skim-app/code/16295
Author:   hofman
Date:     2026-05-23 16:24:47 +0000 (Sat, 23 May 2026)
Log Message:
-----------
Add app extensions for quicklook thumbnailing and preview to support quicklook 
in 15+. Set app version for whole project in config file instead of Info.plist 
and using apple generic versioning, the versions of the app extensions must be 
equal to the app.

Modified Paths:
--------------
    trunk/Configurations/Skim-App.xcconfig
    trunk/Configurations/Skim-Common.xcconfig
    trunk/Info.plist
    trunk/Skim.xcodeproj/project.pbxproj

Added Paths:
-----------
    trunk/Configurations/SkimQuickLookPreview.xcconfig
    trunk/Configurations/SkimQuickLookThumbnails.xcconfig
    trunk/SkimQuickLookPreview/
    trunk/SkimQuickLookPreview/Base.lproj/
    trunk/SkimQuickLookPreview/Circle.png
    trunk/SkimQuickLookPreview/FreeText.png
    trunk/SkimQuickLookPreview/Highlight.png
    trunk/SkimQuickLookPreview/Info.plist
    trunk/SkimQuickLookPreview/Ink.png
    trunk/SkimQuickLookPreview/Line.png
    trunk/SkimQuickLookPreview/New Group/
    trunk/SkimQuickLookPreview/Note.png
    trunk/SkimQuickLookPreview/SKPreviewProvider.h
    trunk/SkimQuickLookPreview/SKPreviewProvider.m
    trunk/SkimQuickLookPreview/SKQLConverter.h
    trunk/SkimQuickLookPreview/SKQLConverter.m
    trunk/SkimQuickLookPreview/SkimQuickLookPreview.entitlements
    trunk/SkimQuickLookPreview/Square.png
    trunk/SkimQuickLookPreview/StrikeOut.png
    trunk/SkimQuickLookPreview/Underline.png
    trunk/SkimQuickLookPreview/Widget.png
    trunk/SkimQuickLookThumbnails/
    trunk/SkimQuickLookThumbnails/Circle.png
    trunk/SkimQuickLookThumbnails/FreeText.png
    trunk/SkimQuickLookThumbnails/Highlight.png
    trunk/SkimQuickLookThumbnails/Info.plist
    trunk/SkimQuickLookThumbnails/Ink.png
    trunk/SkimQuickLookThumbnails/Line.png
    trunk/SkimQuickLookThumbnails/Note.png
    trunk/SkimQuickLookThumbnails/Resources/
    trunk/SkimQuickLookThumbnails/SKQLConverter.h
    trunk/SkimQuickLookThumbnails/SKQLConverter.m
    trunk/SkimQuickLookThumbnails/SKThumbnailProvider.h
    trunk/SkimQuickLookThumbnails/SKThumbnailProvider.m
    trunk/SkimQuickLookThumbnails/Skim.png
    trunk/SkimQuickLookThumbnails/SkimQuickLookThumbnails.entitlements
    trunk/SkimQuickLookThumbnails/Skim_2x.png
    trunk/SkimQuickLookThumbnails/Square.png
    trunk/SkimQuickLookThumbnails/StrikeOut.png
    trunk/SkimQuickLookThumbnails/Underline.png
    trunk/SkimQuickLookThumbnails/Widget.png

Modified: trunk/Configurations/Skim-App.xcconfig
===================================================================
--- trunk/Configurations/Skim-App.xcconfig      2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/Configurations/Skim-App.xcconfig      2026-05-23 16:24:47 UTC (rev 
16295)
@@ -15,6 +15,4 @@
 GCC_PRECOMPILE_PREFIX_HEADER = YES
 GCC_PREFIX_HEADER = Skim_Prefix.pch
 
-VERSIONING_SYSTEM = apple-generic
-
 VALIDATE_WORKSPACE_SKIPPED_SDK_FRAMEWORKS = OpenGL

Modified: trunk/Configurations/Skim-Common.xcconfig
===================================================================
--- trunk/Configurations/Skim-Common.xcconfig   2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/Configurations/Skim-Common.xcconfig   2026-05-23 16:24:47 UTC (rev 
16295)
@@ -3,6 +3,9 @@
 ARCHS = $(ARCHS_STANDARD)
 MACOSX_DEPLOYMENT_TARGET = 10.13
 
+CURRENT_PROJECT_VERSION = 166
+MARKETING_VERSION = 1.7.14
+
 COPY_PHASE_STRIP = NO
 STRIP_INSTALLED_PRODUCT = NO
 STRIP_STYLE = all

Added: trunk/Configurations/SkimQuickLookPreview.xcconfig
===================================================================
--- trunk/Configurations/SkimQuickLookPreview.xcconfig                          
(rev 0)
+++ trunk/Configurations/SkimQuickLookPreview.xcconfig  2026-05-23 16:24:47 UTC 
(rev 16295)
@@ -0,0 +1,15 @@
+MACOSX_DEPLOYMENT_TARGET = 12.0
+INFOPLIST_KEY_CFBundleDisplayName = SkimQuickLookPreview
+
+LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks 
@executable_path/../../../../Frameworks
+
+GENERATE_INFOPLIST_FILE = YES
+INFOPLIST_FILE = SkimQuickLookPreview/Info.plist
+
+PRODUCT_BUNDLE_IDENTIFIER = net.sourceforge.skim-app.skim.quicklook-preview
+PRODUCT_NAME = $(TARGET_NAME)
+
+//CODE_SIGN_ENTITLEMENTS = 
SkimQuickLookPreview/SkimQuickLookPreview.entitlements
+ENABLE_HARDENED_RUNTIME = YES
+
+CLANG_ENABLE_MODULES = YES

Added: trunk/Configurations/SkimQuickLookThumbnails.xcconfig
===================================================================
--- trunk/Configurations/SkimQuickLookThumbnails.xcconfig                       
        (rev 0)
+++ trunk/Configurations/SkimQuickLookThumbnails.xcconfig       2026-05-23 
16:24:47 UTC (rev 16295)
@@ -0,0 +1,15 @@
+MACOSX_DEPLOYMENT_TARGET = 10.15
+INFOPLIST_KEY_CFBundleDisplayName = SkimQuickLookThumbnails
+
+LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks 
@executable_path/../../../../Frameworks
+
+GENERATE_INFOPLIST_FILE = YES
+INFOPLIST_FILE = SkimQuickLookThumbnails/Info.plist
+
+PRODUCT_BUNDLE_IDENTIFIER = net.sourceforge.skim-app.skim.quicklook-thumbnails
+PRODUCT_NAME = $(TARGET_NAME)
+
+//CODE_SIGN_ENTITLEMENTS = 
SkimQuickLookThumbnails/SkimQuickLookThumbnails.entitlements
+ENABLE_HARDENED_RUNTIME = YES
+
+CLANG_ENABLE_MODULES = YES

Modified: trunk/Info.plist
===================================================================
--- trunk/Info.plist    2026-05-14 16:33:34 UTC (rev 16294)
+++ trunk/Info.plist    2026-05-23 16:24:47 UTC (rev 16295)
@@ -310,7 +310,7 @@
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.7.14</string>
+       <string>${MARKETING_VERSION}</string>
        <key>CFBundleSignature</key>
        <string>SKim</string>
        <key>CFBundleURLTypes</key>

Modified: trunk/Skim.xcodeproj/project.pbxproj
===================================================================
--- trunk/Skim.xcodeproj/project.pbxproj        2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/Skim.xcodeproj/project.pbxproj        2026-05-23 16:24:47 UTC (rev 
16295)
@@ -3,7 +3,7 @@
        archiveVersion = 1;
        classes = {
        };
-       objectVersion = 46;
+       objectVersion = 52;
        objects = {
 
 /* Begin PBXAggregateTarget section */
@@ -243,6 +243,37 @@
                CECDC4FF0C5966A80026AAEC /* NSImage_SKExtensions.m in Sources 
*/ = {isa = PBXBuildFile; fileRef = CECDC4FD0C5966A80026AAEC /* 
NSImage_SKExtensions.m */; };
                CECE6C3F2188AE9A00F6179D /* SKSelectionCommand.m in Sources */ 
= {isa = PBXBuildFile; fileRef = CECE6C3E2188AE9A00F6179D /* 
SKSelectionCommand.m */; };
                CECF61FF0DB258D600587D96 /* SKFontWell.m in Sources */ = {isa = 
PBXBuildFile; fileRef = CECF61FE0DB258D600587D96 /* SKFontWell.m */; };
+               CED2D2FA2FC0FDF70044A3DC /* QuickLookThumbnailing.framework in 
Frameworks */ = {isa = PBXBuildFile; fileRef = CED2D2F92FC0FDF70044A3DC /* 
QuickLookThumbnailing.framework */; platformFilter = maccatalyst; };
+               CED2D2FC2FC0FDF70044A3DC /* Quartz.framework in Frameworks */ = 
{isa = PBXBuildFile; fileRef = CED2D2FB2FC0FDF70044A3DC /* Quartz.framework */; 
};
+               CED2D3002FC0FDF70044A3DC /* SKThumbnailProvider.m in Sources */ 
= {isa = PBXBuildFile; fileRef = CED2D2FF2FC0FDF70044A3DC /* 
SKThumbnailProvider.m */; };
+               CED2D3052FC0FDF70044A3DC /* SkimQuickLookThumbnails.appex in 
CopyFiles */ = {isa = PBXBuildFile; fileRef = CED2D2F82FC0FDF70044A3DC /* 
SkimQuickLookThumbnails.appex */; settings = {ATTRIBUTES = 
(RemoveHeadersOnCopy, ); }; };
+               CED2D3252FC103860044A3DC /* SKQLConverter.m in Sources */ = 
{isa = PBXBuildFile; fileRef = CED2D3242FC103860044A3DC /* SKQLConverter.m */; 
};
+               CED2D3332FC108210044A3DC /* Underline.png in Resources */ = 
{isa = PBXBuildFile; fileRef = CED2D3272FC108200044A3DC /* Underline.png */; };
+               CED2D3342FC108210044A3DC /* FreeText.png in Resources */ = {isa 
= PBXBuildFile; fileRef = CED2D3282FC108200044A3DC /* FreeText.png */; };
+               CED2D3352FC108210044A3DC /* Ink.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D3292FC108200044A3DC /* Ink.png */; };
+               CED2D3362FC108210044A3DC /* Circle.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D32A2FC108200044A3DC /* Circle.png */; };
+               CED2D3372FC108210044A3DC /* Line.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D32B2FC108200044A3DC /* Line.png */; };
+               CED2D3382FC108210044A3DC /* Square.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D32C2FC108200044A3DC /* Square.png */; };
+               CED2D3392FC108210044A3DC /* Widget.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D32D2FC108200044A3DC /* Widget.png */; };
+               CED2D33A2FC108210044A3DC /* Highlight.png in Resources */ = 
{isa = PBXBuildFile; fileRef = CED2D32E2FC108200044A3DC /* Highlight.png */; };
+               CED2D33B2FC108210044A3DC /* Note.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D32F2FC108200044A3DC /* Note.png */; };
+               CED2D33C2FC108210044A3DC /* StrikeOut.png in Resources */ = 
{isa = PBXBuildFile; fileRef = CED2D3302FC108200044A3DC /* StrikeOut.png */; };
+               CED2D33D2FC108210044A3DC /* Skim_2x.png in Resources */ = {isa 
= PBXBuildFile; fileRef = CED2D3312FC108210044A3DC /* Skim_2x.png */; };
+               CED2D33E2FC108210044A3DC /* Skim.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D3322FC108210044A3DC /* Skim.png */; };
+               CED2D3462FC10BA80044A3DC /* Quartz.framework in Frameworks */ = 
{isa = PBXBuildFile; fileRef = CED2D2FB2FC0FDF70044A3DC /* Quartz.framework */; 
};
+               CED2D34D2FC10BA80044A3DC /* SKPreviewProvider.m in Sources */ = 
{isa = PBXBuildFile; fileRef = CED2D34C2FC10BA80044A3DC /* SKPreviewProvider.m 
*/; };
+               CED2D3552FC10BA80044A3DC /* SkimQuickLookPreview.appex in 
CopyFiles */ = {isa = PBXBuildFile; fileRef = CED2D3452FC10BA80044A3DC /* 
SkimQuickLookPreview.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, 
); }; };
+               CED2D35E2FC10EA80044A3DC /* SKQLConverter.m in Sources */ = 
{isa = PBXBuildFile; fileRef = CED2D35D2FC10EA80044A3DC /* SKQLConverter.m */; 
};
+               CED2D3692FC113B60044A3DC /* Widget.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D35F2FC113B50044A3DC /* Widget.png */; };
+               CED2D36A2FC113B60044A3DC /* StrikeOut.png in Resources */ = 
{isa = PBXBuildFile; fileRef = CED2D3602FC113B60044A3DC /* StrikeOut.png */; };
+               CED2D36B2FC113B60044A3DC /* Line.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D3612FC113B60044A3DC /* Line.png */; };
+               CED2D36C2FC113B60044A3DC /* Note.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D3622FC113B60044A3DC /* Note.png */; };
+               CED2D36D2FC113B60044A3DC /* Square.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D3632FC113B60044A3DC /* Square.png */; };
+               CED2D36E2FC113B60044A3DC /* Underline.png in Resources */ = 
{isa = PBXBuildFile; fileRef = CED2D3642FC113B60044A3DC /* Underline.png */; };
+               CED2D36F2FC113B60044A3DC /* Ink.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D3652FC113B60044A3DC /* Ink.png */; };
+               CED2D3702FC113B60044A3DC /* Highlight.png in Resources */ = 
{isa = PBXBuildFile; fileRef = CED2D3662FC113B60044A3DC /* Highlight.png */; };
+               CED2D3712FC113B60044A3DC /* Circle.png in Resources */ = {isa = 
PBXBuildFile; fileRef = CED2D3672FC113B60044A3DC /* Circle.png */; };
+               CED2D3722FC113B60044A3DC /* FreeText.png in Resources */ = {isa 
= PBXBuildFile; fileRef = CED2D3682FC113B60044A3DC /* FreeText.png */; };
                CED4DA252707B330001E09A8 /* SKThumbnailImageView.m in Sources 
*/ = {isa = PBXBuildFile; fileRef = CED4DA242707B330001E09A8 /* 
SKThumbnailImageView.m */; };
                CED76F011A1825DE00D1ACA4 /* SKScrollView.m in Sources */ = {isa 
= PBXBuildFile; fileRef = CED76F001A1825DE00D1ACA4 /* SKScrollView.m */; };
                CEDA057B2295BEBA00881DE1 /* SkimTransitions.plugin in CopyFiles 
*/ = {isa = PBXBuildFile; fileRef = CEDA056B2295BE8300881DE1 /* 
SkimTransitions.plugin */; settings = {ATTRIBUTES = (CodeSignOnCopy, 
RemoveHeadersOnCopy, ); }; };
@@ -524,6 +555,20 @@
                        remoteGlobalIDString = 8D576316048677EA00EA77CD;
                        remoteInfo = Skim;
                };
+               CED2D3032FC0FDF70044A3DC /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 2A37F4A9FDCFA73011CA2CEA /* Project 
object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = CED2D2F72FC0FDF70044A3DC;
+                       remoteInfo = SkimQuickLookThumbnails;
+               };
+               CED2D3532FC10BA80044A3DC /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 2A37F4A9FDCFA73011CA2CEA /* Project 
object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = CED2D3442FC10BA80044A3DC;
+                       remoteInfo = SkimQuickLookPreview;
+               };
                CEDA056A2295BE8300881DE1 /* PBXContainerItemProxy */ = {
                        isa = PBXContainerItemProxy;
                        containerPortal = CEDA05622295BE8300881DE1 /* 
SkimTransitions.xcodeproj */;
@@ -586,6 +631,8 @@
                        dstPath = "";
                        dstSubfolderSpec = 13;
                        files = (
+                               CED2D3052FC0FDF70044A3DC /* 
SkimQuickLookThumbnails.appex in CopyFiles */,
+                               CED2D3552FC10BA80044A3DC /* 
SkimQuickLookPreview.appex in CopyFiles */,
                                CEDA057B2295BEBA00881DE1 /* 
SkimTransitions.plugin in CopyFiles */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
@@ -1172,6 +1219,46 @@
                CECE6C3E2188AE9A00F6179D /* SKSelectionCommand.m */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = 
SKSelectionCommand.m; sourceTree = "<group>"; };
                CECF61FD0DB258D600587D96 /* SKFontWell.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
SKFontWell.h; sourceTree = "<group>"; };
                CECF61FE0DB258D600587D96 /* SKFontWell.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= SKFontWell.m; sourceTree = "<group>"; };
+               CED2D2F82FC0FDF70044A3DC /* SkimQuickLookThumbnails.appex */ = 
{isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; 
includeInIndex = 0; path = SkimQuickLookThumbnails.appex; sourceTree = 
BUILT_PRODUCTS_DIR; };
+               CED2D2F92FC0FDF70044A3DC /* QuickLookThumbnailing.framework */ 
= {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = 
QuickLookThumbnailing.framework; path = 
System/Library/Frameworks/QuickLookThumbnailing.framework; sourceTree = 
SDKROOT; };
+               CED2D2FB2FC0FDF70044A3DC /* Quartz.framework */ = {isa = 
PBXFileReference; lastKnownFileType = wrapper.framework; name = 
Quartz.framework; path = System/Library/Frameworks/Quartz.framework; sourceTree 
= SDKROOT; };
+               CED2D2FE2FC0FDF70044A3DC /* SKThumbnailProvider.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
SKThumbnailProvider.h; sourceTree = "<group>"; };
+               CED2D2FF2FC0FDF70044A3DC /* SKThumbnailProvider.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= SKThumbnailProvider.m; sourceTree = "<group>"; };
+               CED2D3012FC0FDF70044A3DC /* Info.plist */ = {isa = 
PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; 
sourceTree = "<group>"; };
+               CED2D3022FC0FDF70044A3DC /* 
SkimQuickLookThumbnails.entitlements */ = {isa = PBXFileReference; 
lastKnownFileType = text.plist.entitlements; path = 
SkimQuickLookThumbnails.entitlements; sourceTree = "<group>"; };
+               CED2D3232FC103860044A3DC /* SKQLConverter.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
SKQLConverter.h; sourceTree = "<group>"; };
+               CED2D3242FC103860044A3DC /* SKQLConverter.m */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path 
= SKQLConverter.m; sourceTree = "<group>"; };
+               CED2D3272FC108200044A3DC /* Underline.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Underline.png; 
sourceTree = "<group>"; };
+               CED2D3282FC108200044A3DC /* FreeText.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = FreeText.png; 
sourceTree = "<group>"; };
+               CED2D3292FC108200044A3DC /* Ink.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Ink.png; sourceTree = 
"<group>"; };
+               CED2D32A2FC108200044A3DC /* Circle.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Circle.png; sourceTree 
= "<group>"; };
+               CED2D32B2FC108200044A3DC /* Line.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Line.png; sourceTree = 
"<group>"; };
+               CED2D32C2FC108200044A3DC /* Square.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Square.png; sourceTree 
= "<group>"; };
+               CED2D32D2FC108200044A3DC /* Widget.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Widget.png; sourceTree 
= "<group>"; };
+               CED2D32E2FC108200044A3DC /* Highlight.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Highlight.png; 
sourceTree = "<group>"; };
+               CED2D32F2FC108200044A3DC /* Note.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Note.png; sourceTree = 
"<group>"; };
+               CED2D3302FC108200044A3DC /* StrikeOut.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = StrikeOut.png; 
sourceTree = "<group>"; };
+               CED2D3312FC108210044A3DC /* Skim_2x.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Skim_2x.png; sourceTree 
= "<group>"; };
+               CED2D3322FC108210044A3DC /* Skim.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Skim.png; sourceTree = 
"<group>"; };
+               CED2D3402FC1092D0044A3DC /* SkimQuickLookThumbnails.xcconfig */ 
= {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = 
SkimQuickLookThumbnails.xcconfig; sourceTree = "<group>"; };
+               CED2D3452FC10BA80044A3DC /* SkimQuickLookPreview.appex */ = 
{isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; 
includeInIndex = 0; path = SkimQuickLookPreview.appex; sourceTree = 
BUILT_PRODUCTS_DIR; };
+               CED2D34B2FC10BA80044A3DC /* SKPreviewProvider.h */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.c.h; path = 
SKPreviewProvider.h; sourceTree = "<group>"; };
+               CED2D34C2FC10BA80044A3DC /* SKPreviewProvider.m */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = 
SKPreviewProvider.m; sourceTree = "<group>"; };
+               CED2D3512FC10BA80044A3DC /* Info.plist */ = {isa = 
PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; 
sourceTree = "<group>"; };
+               CED2D3522FC10BA80044A3DC /* SkimQuickLookPreview.entitlements 
*/ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path 
= SkimQuickLookPreview.entitlements; sourceTree = "<group>"; };
+               CED2D35B2FC10C860044A3DC /* SkimQuickLookPreview.xcconfig */ = 
{isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = 
SkimQuickLookPreview.xcconfig; sourceTree = "<group>"; };
+               CED2D35C2FC10EA80044A3DC /* SKQLConverter.h */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SKQLConverter.h; 
sourceTree = "<group>"; };
+               CED2D35D2FC10EA80044A3DC /* SKQLConverter.m */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = 
SKQLConverter.m; sourceTree = "<group>"; };
+               CED2D35F2FC113B50044A3DC /* Widget.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Widget.png; sourceTree 
= "<group>"; };
+               CED2D3602FC113B60044A3DC /* StrikeOut.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = StrikeOut.png; 
sourceTree = "<group>"; };
+               CED2D3612FC113B60044A3DC /* Line.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Line.png; sourceTree = 
"<group>"; };
+               CED2D3622FC113B60044A3DC /* Note.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Note.png; sourceTree = 
"<group>"; };
+               CED2D3632FC113B60044A3DC /* Square.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Square.png; sourceTree 
= "<group>"; };
+               CED2D3642FC113B60044A3DC /* Underline.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Underline.png; 
sourceTree = "<group>"; };
+               CED2D3652FC113B60044A3DC /* Ink.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Ink.png; sourceTree = 
"<group>"; };
+               CED2D3662FC113B60044A3DC /* Highlight.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Highlight.png; 
sourceTree = "<group>"; };
+               CED2D3672FC113B60044A3DC /* Circle.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = Circle.png; sourceTree 
= "<group>"; };
+               CED2D3682FC113B60044A3DC /* FreeText.png */ = {isa = 
PBXFileReference; lastKnownFileType = image.png; path = FreeText.png; 
sourceTree = "<group>"; };
                CED4DA232707B330001E09A8 /* SKThumbnailImageView.h */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.c.h; path = 
SKThumbnailImageView.h; sourceTree = "<group>"; };
                CED4DA242707B330001E09A8 /* SKThumbnailImageView.m */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = 
SKThumbnailImageView.m; sourceTree = "<group>"; };
                CED76EFF1A1825DE00D1ACA4 /* SKScrollView.h */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = 
SKScrollView.h; sourceTree = "<group>"; };
@@ -1449,6 +1536,23 @@
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               CED2D2F52FC0FDF70044A3DC /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               CED2D2FA2FC0FDF70044A3DC /* 
QuickLookThumbnailing.framework in Frameworks */,
+                               CED2D2FC2FC0FDF70044A3DC /* Quartz.framework in 
Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               CED2D3422FC10BA80044A3DC /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               CED2D3462FC10BA80044A3DC /* Quartz.framework in 
Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
@@ -1478,6 +1582,8 @@
                        isa = PBXGroup;
                        children = (
                                8D15AC370486D014006FF6A4 /* Skim.app */,
+                               CED2D2F82FC0FDF70044A3DC /* 
SkimQuickLookThumbnails.appex */,
+                               CED2D3452FC10BA80044A3DC /* 
SkimQuickLookPreview.appex */,
                        );
                        name = Products;
                        sourceTree = "<group>";
@@ -1493,6 +1599,8 @@
                                2A37F4B8FDCFA73011CA2CEA /* Resources */,
                                CEE22EA20BFB8631002B746B /* Shared Support */,
                                CE2BD8160BD4123D00A5F4DB /* Subprojects */,
+                               CED2D2FD2FC0FDF70044A3DC /* 
SkimQuickLookThumbnails */,
+                               CED2D3472FC10BA80044A3DC /* 
SkimQuickLookPreview */,
                                2A37F4C3FDCFA73011CA2CEA /* Frameworks */,
                                19C28FB0FE9D524F11CA2CBB /* Products */,
                                CED8D4050D744D520028E3E2 /* Configurations */,
@@ -1560,6 +1668,8 @@
                                CE0998CA0EC8EC2A006CD0F7 /* Linked Libraries */,
                                1058C7A6FEA54F5311CA2CBB /* Linked Frameworks 
*/,
                                CE2BB81B0E0DB4FA0090E848 /* Embedded Frameworks 
*/,
+                               CED2D2F92FC0FDF70044A3DC /* 
QuickLookThumbnailing.framework */,
+                               CED2D2FB2FC0FDF70044A3DC /* Quartz.framework */,
                                1058C7A8FEA54F5311CA2CBB /* Other Frameworks */,
                        );
                        name = Frameworks;
@@ -2109,6 +2219,86 @@
                        name = Products;
                        sourceTree = "<group>";
                };
+               CED2D2FD2FC0FDF70044A3DC /* SkimQuickLookThumbnails */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CED2D33F2FC1085B0044A3DC /* Source */,
+                               CED2D3262FC107C80044A3DC /* Resources */,
+                               CED2D3022FC0FDF70044A3DC /* 
SkimQuickLookThumbnails.entitlements */,
+                       );
+                       path = SkimQuickLookThumbnails;
+                       sourceTree = "<group>";
+               };
+               CED2D3262FC107C80044A3DC /* Resources */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CED2D3322FC108210044A3DC /* Skim.png */,
+                               CED2D3312FC108210044A3DC /* Skim_2x.png */,
+                               CED2D3302FC108200044A3DC /* StrikeOut.png */,
+                               CED2D32F2FC108200044A3DC /* Note.png */,
+                               CED2D32B2FC108200044A3DC /* Line.png */,
+                               CED2D32C2FC108200044A3DC /* Square.png */,
+                               CED2D3282FC108200044A3DC /* FreeText.png */,
+                               CED2D32A2FC108200044A3DC /* Circle.png */,
+                               CED2D3272FC108200044A3DC /* Underline.png */,
+                               CED2D32E2FC108200044A3DC /* Highlight.png */,
+                               CED2D3292FC108200044A3DC /* Ink.png */,
+                               CED2D32D2FC108200044A3DC /* Widget.png */,
+                               CED2D3012FC0FDF70044A3DC /* Info.plist */,
+                       );
+                       name = Resources;
+                       sourceTree = "<group>";
+               };
+               CED2D33F2FC1085B0044A3DC /* Source */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CED2D2FE2FC0FDF70044A3DC /* 
SKThumbnailProvider.h */,
+                               CED2D2FF2FC0FDF70044A3DC /* 
SKThumbnailProvider.m */,
+                               CED2D3232FC103860044A3DC /* SKQLConverter.h */,
+                               CED2D3242FC103860044A3DC /* SKQLConverter.m */,
+                       );
+                       name = Source;
+                       sourceTree = "<group>";
+               };
+               CED2D3472FC10BA80044A3DC /* SkimQuickLookPreview */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CED2D3592FC10C330044A3DC /* Source */,
+                               CED2D35A2FC10C4F0044A3DC /* Resources */,
+                               CED2D3522FC10BA80044A3DC /* 
SkimQuickLookPreview.entitlements */,
+                       );
+                       path = SkimQuickLookPreview;
+                       sourceTree = "<group>";
+               };
+               CED2D3592FC10C330044A3DC /* Source */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CED2D34B2FC10BA80044A3DC /* SKPreviewProvider.h 
*/,
+                               CED2D34C2FC10BA80044A3DC /* SKPreviewProvider.m 
*/,
+                               CED2D35C2FC10EA80044A3DC /* SKQLConverter.h */,
+                               CED2D35D2FC10EA80044A3DC /* SKQLConverter.m */,
+                       );
+                       name = Source;
+                       sourceTree = "<group>";
+               };
+               CED2D35A2FC10C4F0044A3DC /* Resources */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CED2D3602FC113B60044A3DC /* StrikeOut.png */,
+                               CED2D3622FC113B60044A3DC /* Note.png */,
+                               CED2D3612FC113B60044A3DC /* Line.png */,
+                               CED2D3632FC113B60044A3DC /* Square.png */,
+                               CED2D3682FC113B60044A3DC /* FreeText.png */,
+                               CED2D3672FC113B60044A3DC /* Circle.png */,
+                               CED2D3642FC113B60044A3DC /* Underline.png */,
+                               CED2D3662FC113B60044A3DC /* Highlight.png */,
+                               CED2D3652FC113B60044A3DC /* Ink.png */,
+                               CED2D35F2FC113B50044A3DC /* Widget.png */,
+                               CED2D3512FC10BA80044A3DC /* Info.plist */,
+                       );
+                       name = Resources;
+                       sourceTree = "<group>";
+               };
                CED8D4050D744D520028E3E2 /* Configurations */ = {
                        isa = PBXGroup;
                        children = (
@@ -2116,6 +2306,8 @@
                                CED8D40C0D744D940028E3E2 /* Skim-Debug.xcconfig 
*/,
                                CED8D40D0D744D940028E3E2 /* 
Skim-Release.xcconfig */,
                                CE17EE460E24ED7C00DE06EA /* Skim-App.xcconfig 
*/,
+                               CED2D3402FC1092D0044A3DC /* 
SkimQuickLookThumbnails.xcconfig */,
+                               CED2D35B2FC10C860044A3DC /* 
SkimQuickLookPreview.xcconfig */,
                        );
                        path = Configurations;
                        sourceTree = "<group>";
@@ -2306,6 +2498,8 @@
                                CE816A030D70F8F7008D807D /* PBXTargetDependency 
*/,
                                CE7DC7E20E093C1A00D6D76D /* PBXTargetDependency 
*/,
                                CEFF6B9C122B1478008CDE73 /* PBXTargetDependency 
*/,
+                               CED2D3042FC0FDF70044A3DC /* PBXTargetDependency 
*/,
+                               CED2D3542FC10BA80044A3DC /* PBXTargetDependency 
*/,
                        );
                        name = Skim;
                        productInstallPath = "$(HOME)/Applications";
@@ -2313,6 +2507,40 @@
                        productReference = 8D15AC370486D014006FF6A4 /* Skim.app 
*/;
                        productType = "com.apple.product-type.application";
                };
+               CED2D2F72FC0FDF70044A3DC /* SkimQuickLookThumbnails */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = CED2D3222FC0FDF70044A3DC /* 
Build configuration list for PBXNativeTarget "SkimQuickLookThumbnails" */;
+                       buildPhases = (
+                               CED2D2F42FC0FDF70044A3DC /* Sources */,
+                               CED2D2F52FC0FDF70044A3DC /* Frameworks */,
+                               CED2D2F62FC0FDF70044A3DC /* Resources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = SkimQuickLookThumbnails;
+                       productName = SkimQuickLookThumbnails;
+                       productReference = CED2D2F82FC0FDF70044A3DC /* 
SkimQuickLookThumbnails.appex */;
+                       productType = "com.apple.product-type.app-extension";
+               };
+               CED2D3442FC10BA80044A3DC /* SkimQuickLookPreview */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = CED2D3562FC10BA80044A3DC /* 
Build configuration list for PBXNativeTarget "SkimQuickLookPreview" */;
+                       buildPhases = (
+                               CED2D3412FC10BA80044A3DC /* Sources */,
+                               CED2D3422FC10BA80044A3DC /* Frameworks */,
+                               CED2D3432FC10BA80044A3DC /* Resources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = SkimQuickLookPreview;
+                       productName = SkimQuickLookPreview;
+                       productReference = CED2D3452FC10BA80044A3DC /* 
SkimQuickLookPreview.appex */;
+                       productType = "com.apple.product-type.app-extension";
+               };
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
@@ -2320,6 +2548,14 @@
                        isa = PBXProject;
                        attributes = {
                                LastUpgradeCheck = 1320;
+                               TargetAttributes = {
+                                       CED2D2F72FC0FDF70044A3DC = {
+                                               CreatedOnToolsVersion = 13.2.1;
+                                       };
+                                       CED2D3442FC10BA80044A3DC = {
+                                               CreatedOnToolsVersion = 13.2.1;
+                                       };
+                               };
                        };
                        buildConfigurationList = C05733CB08A9546B00998B17 /* 
Build configuration list for PBXProject "Skim" */;
                        compatibilityVersion = "Xcode 3.2";
@@ -2370,6 +2606,8 @@
                        targets = (
                                8D15AC270486D014006FF6A4 /* Skim */,
                                CE592C5D0B9239C500C113DF /* DiskImage */,
+                               CED2D2F72FC0FDF70044A3DC /* 
SkimQuickLookThumbnails */,
+                               CED2D3442FC10BA80044A3DC /* 
SkimQuickLookPreview */,
                        );
                };
 /* End PBXProject section */
@@ -2659,6 +2897,42 @@
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               CED2D2F62FC0FDF70044A3DC /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               CED2D33B2FC108210044A3DC /* Note.png in 
Resources */,
+                               CED2D33A2FC108210044A3DC /* Highlight.png in 
Resources */,
+                               CED2D3352FC108210044A3DC /* Ink.png in 
Resources */,
+                               CED2D33E2FC108210044A3DC /* Skim.png in 
Resources */,
+                               CED2D3342FC108210044A3DC /* FreeText.png in 
Resources */,
+                               CED2D33C2FC108210044A3DC /* StrikeOut.png in 
Resources */,
+                               CED2D3372FC108210044A3DC /* Line.png in 
Resources */,
+                               CED2D3332FC108210044A3DC /* Underline.png in 
Resources */,
+                               CED2D3382FC108210044A3DC /* Square.png in 
Resources */,
+                               CED2D3362FC108210044A3DC /* Circle.png in 
Resources */,
+                               CED2D3392FC108210044A3DC /* Widget.png in 
Resources */,
+                               CED2D33D2FC108210044A3DC /* Skim_2x.png in 
Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               CED2D3432FC10BA80044A3DC /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               CED2D3702FC113B60044A3DC /* Highlight.png in 
Resources */,
+                               CED2D3712FC113B60044A3DC /* Circle.png in 
Resources */,
+                               CED2D36D2FC113B60044A3DC /* Square.png in 
Resources */,
+                               CED2D36B2FC113B60044A3DC /* Line.png in 
Resources */,
+                               CED2D36E2FC113B60044A3DC /* Underline.png in 
Resources */,
+                               CED2D36C2FC113B60044A3DC /* Note.png in 
Resources */,
+                               CED2D36F2FC113B60044A3DC /* Ink.png in 
Resources */,
+                               CED2D36A2FC113B60044A3DC /* StrikeOut.png in 
Resources */,
+                               CED2D3722FC113B60044A3DC /* FreeText.png in 
Resources */,
+                               CED2D3692FC113B60044A3DC /* Widget.png in 
Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
@@ -2978,6 +3252,24 @@
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
+               CED2D2F42FC0FDF70044A3DC /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               CED2D3002FC0FDF70044A3DC /* 
SKThumbnailProvider.m in Sources */,
+                               CED2D3252FC103860044A3DC /* SKQLConverter.m in 
Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               CED2D3412FC10BA80044A3DC /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               CED2D34D2FC10BA80044A3DC /* SKPreviewProvider.m 
in Sources */,
+                               CED2D35E2FC10EA80044A3DC /* SKQLConverter.m in 
Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
 /* End PBXSourcesBuildPhase section */
 
 /* Begin PBXTargetDependency section */
@@ -3006,6 +3298,16 @@
                        name = Skim;
                        targetProxy = CE816A020D70F8F7008D807D /* 
PBXContainerItemProxy */;
                };
+               CED2D3042FC0FDF70044A3DC /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = CED2D2F72FC0FDF70044A3DC /* 
SkimQuickLookThumbnails */;
+                       targetProxy = CED2D3032FC0FDF70044A3DC /* 
PBXContainerItemProxy */;
+               };
+               CED2D3542FC10BA80044A3DC /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = CED2D3442FC10BA80044A3DC /* 
SkimQuickLookPreview */;
+                       targetProxy = CED2D3532FC10BA80044A3DC /* 
PBXContainerItemProxy */;
+               };
                CEDA05792295BE8B00881DE1 /* PBXTargetDependency */ = {
                        isa = PBXTargetDependency;
                        name = SkimTransitions;
@@ -3779,7 +4081,6 @@
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = CE17EE460E24ED7C00DE06EA 
/* Skim-App.xcconfig */;
                        buildSettings = {
-                               CURRENT_PROJECT_VERSION = 166;
                        };
                        name = Debug;
                };
@@ -3787,7 +4088,6 @@
                        isa = XCBuildConfiguration;
                        baseConfigurationReference = CE17EE460E24ED7C00DE06EA 
/* Skim-App.xcconfig */;
                        buildSettings = {
-                               CURRENT_PROJECT_VERSION = 166;
                        };
                        name = Release;
                };
@@ -3819,6 +4119,217 @@
                        };
                        name = Release;
                };
+               CED2D3062FC0FDF70044A3DC /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = CED2D3402FC1092D0044A3DC 
/* SkimQuickLookThumbnails.xcconfig */;
+                       buildSettings = {
+                               CLANG_ANALYZER_NONNULL = YES;
+                               CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = 
YES_AGGRESSIVE;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_ENABLE_OBJC_WEAK = YES;
+                               CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_COMMA = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 
YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+                               CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = 
YES;
+                               CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+                               CLANG_WARN_STRICT_PROTOTYPES = YES;
+                               CLANG_WARN_SUSPICIOUS_MOVE = YES;
+                               CLANG_WARN_UNGUARDED_AVAILABILITY = 
YES_AGGRESSIVE;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               ENABLE_HARDENED_RUNTIME = YES;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu11;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_NO_COMMON_BLOCKS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INFOPLIST_KEY_CFBundleDisplayName = 
SkimQuickLookThumbnails;
+                               MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+                               MTL_FAST_MATH = YES;
+                               SWIFT_EMIT_LOC_STRINGS = YES;
+                       };
+                       name = Debug;
+               };
+               CED2D3072FC0FDF70044A3DC /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = CED2D3402FC1092D0044A3DC 
/* SkimQuickLookThumbnails.xcconfig */;
+                       buildSettings = {
+                               CLANG_ANALYZER_NONNULL = YES;
+                               CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = 
YES_AGGRESSIVE;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_ENABLE_OBJC_WEAK = YES;
+                               CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_COMMA = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 
YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+                               CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = 
YES;
+                               CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+                               CLANG_WARN_STRICT_PROTOTYPES = YES;
+                               CLANG_WARN_SUSPICIOUS_MOVE = YES;
+                               CLANG_WARN_UNGUARDED_AVAILABILITY = 
YES_AGGRESSIVE;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               ENABLE_HARDENED_RUNTIME = YES;
+                               ENABLE_NS_ASSERTIONS = NO;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu11;
+                               GCC_NO_COMMON_BLOCKS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INFOPLIST_KEY_CFBundleDisplayName = 
SkimQuickLookThumbnails;
+                               MTL_ENABLE_DEBUG_INFO = NO;
+                               MTL_FAST_MATH = YES;
+                               SWIFT_EMIT_LOC_STRINGS = YES;
+                       };
+                       name = Release;
+               };
+               CED2D3572FC10BA80044A3DC /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = CED2D35B2FC10C860044A3DC 
/* SkimQuickLookPreview.xcconfig */;
+                       buildSettings = {
+                               CLANG_ANALYZER_NONNULL = YES;
+                               CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = 
YES_AGGRESSIVE;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_ENABLE_OBJC_WEAK = YES;
+                               CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_COMMA = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 
YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+                               CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = 
YES;
+                               CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+                               CLANG_WARN_STRICT_PROTOTYPES = YES;
+                               CLANG_WARN_SUSPICIOUS_MOVE = YES;
+                               CLANG_WARN_UNGUARDED_AVAILABILITY = 
YES_AGGRESSIVE;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu11;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_NO_COMMON_BLOCKS = YES;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INFOPLIST_KEY_CFBundleDisplayName = 
SkimQuickLookPreview;
+                               MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+                               MTL_FAST_MATH = YES;
+                               SWIFT_EMIT_LOC_STRINGS = YES;
+                       };
+                       name = Debug;
+               };
+               CED2D3582FC10BA80044A3DC /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = CED2D35B2FC10C860044A3DC 
/* SkimQuickLookPreview.xcconfig */;
+                       buildSettings = {
+                               CLANG_ANALYZER_NONNULL = YES;
+                               CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = 
YES_AGGRESSIVE;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_ENABLE_OBJC_WEAK = YES;
+                               CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_COMMA = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 
YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+                               CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = 
YES;
+                               CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+                               CLANG_WARN_STRICT_PROTOTYPES = YES;
+                               CLANG_WARN_SUSPICIOUS_MOVE = YES;
+                               CLANG_WARN_UNGUARDED_AVAILABILITY = 
YES_AGGRESSIVE;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               ENABLE_NS_ASSERTIONS = NO;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu11;
+                               GCC_NO_COMMON_BLOCKS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               INFOPLIST_KEY_CFBundleDisplayName = 
SkimQuickLookPreview;
+                               MTL_ENABLE_DEBUG_INFO = NO;
+                               MTL_FAST_MATH = YES;
+                               SWIFT_EMIT_LOC_STRINGS = YES;
+                       };
+                       name = Release;
+               };
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
@@ -3849,6 +4360,24 @@
                        defaultConfigurationIsVisible = 0;
                        defaultConfigurationName = Release;
                };
+               CED2D3222FC0FDF70044A3DC /* Build configuration list for 
PBXNativeTarget "SkimQuickLookThumbnails" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               CED2D3062FC0FDF70044A3DC /* Debug */,
+                               CED2D3072FC0FDF70044A3DC /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               CED2D3562FC10BA80044A3DC /* Build configuration list for 
PBXNativeTarget "SkimQuickLookPreview" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               CED2D3572FC10BA80044A3DC /* Debug */,
+                               CED2D3582FC10BA80044A3DC /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
 /* End XCConfigurationList section */
        };
        rootObject = 2A37F4A9FDCFA73011CA2CEA /* Project object */;

Added: trunk/SkimQuickLookPreview/Circle.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookPreview/Circle.png
===================================================================
--- trunk/SkimQuickLookPreview/Circle.png       2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookPreview/Circle.png       2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookPreview/Circle.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/FreeText.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookPreview/FreeText.png
===================================================================
--- trunk/SkimQuickLookPreview/FreeText.png     2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookPreview/FreeText.png     2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookPreview/FreeText.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Highlight.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookPreview/Highlight.png
===================================================================
--- trunk/SkimQuickLookPreview/Highlight.png    2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookPreview/Highlight.png    2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookPreview/Highlight.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Info.plist
===================================================================
--- trunk/SkimQuickLookPreview/Info.plist                               (rev 0)
+++ trunk/SkimQuickLookPreview/Info.plist       2026-05-23 16:24:47 UTC (rev 
16295)
@@ -0,0 +1,89 @@
+<?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>
+                       <true/>
+                       <key>QLSupportedContentTypes</key>
+                       <array>
+                               <string>net.sourceforge.skim-app.pdfd</string>
+                               
<string>net.sourceforge.skim-app.skimnotes</string>
+                               <string>com.adobe.postscript</string>
+                       </array>
+                       <key>QLSupportsSearchableItems</key>
+                       <false/>
+               </dict>
+               <key>NSExtensionPointIdentifier</key>
+               <string>com.apple.quicklook.preview</string>
+               <key>NSExtensionPrincipalClass</key>
+               <string>SKPreviewViewController</string>
+       </dict>
+       <key>UTImportedTypeDeclarations</key>
+       <array>
+               <dict>
+                       <key>UTTypeConformsTo</key>
+                       <array>
+                               <string>com.apple.package</string>
+                               <string>public.composite-content</string>
+                       </array>
+                       <key>UTTypeDescription</key>
+                       <string>PDF Bundle</string>
+                       <key>UTTypeIdentifier</key>
+                       <string>net.sourceforge.skim-app.pdfd</string>
+                       <key>UTTypeTagSpecification</key>
+                       <dict>
+                               <key>com.apple.ostype</key>
+                               <string>PDFD</string>
+                               <key>public.filename-extension</key>
+                               <array>
+                                       <string>pdfd</string>
+                               </array>
+                       </dict>
+               </dict>
+               <dict>
+                       <key>UTTypeConformsTo</key>
+                       <array>
+                               <string>public.data</string>
+                       </array>
+                       <key>UTTypeDescription</key>
+                       <string>Skim Notes</string>
+                       <key>UTTypeIdentifier</key>
+                       <string>net.sourceforge.skim-app.skimnotes</string>
+                       <key>UTTypeTagSpecification</key>
+                       <dict>
+                               <key>com.apple.ostype</key>
+                               <string>SKNT</string>
+                               <key>public.filename-extension</key>
+                               <array>
+                                       <string>skim</string>
+                               </array>
+                       </dict>
+               </dict>
+               <dict>
+                       <key>UTTypeConformsTo</key>
+                       <array>
+                               <string>public.data</string>
+                       </array>
+                       <key>UTTypeDescription</key>
+                       <string>PostScript</string>
+                       <key>UTTypeIdentifier</key>
+                       <string>com.adobe.postscript</string>
+                       <key>UTTypeTagSpecification</key>
+                       <dict>
+                               <key>public.filename-extension</key>
+                               <array>
+                                       <string>ps</string>
+                               </array>
+                               <key>public.mime-type</key>
+                               <array>
+                                       <string>application/postscript</string>
+                               </array>
+                       </dict>
+               </dict>
+       </array>
+</dict>
+</plist>

Added: trunk/SkimQuickLookPreview/Ink.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookPreview/Ink.png
===================================================================
--- trunk/SkimQuickLookPreview/Ink.png  2026-05-14 16:33:34 UTC (rev 16294)
+++ trunk/SkimQuickLookPreview/Ink.png  2026-05-23 16:24:47 UTC (rev 16295)

Property changes on: trunk/SkimQuickLookPreview/Ink.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Line.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookPreview/Line.png
===================================================================
--- trunk/SkimQuickLookPreview/Line.png 2026-05-14 16:33:34 UTC (rev 16294)
+++ trunk/SkimQuickLookPreview/Line.png 2026-05-23 16:24:47 UTC (rev 16295)

Property changes on: trunk/SkimQuickLookPreview/Line.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Note.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookPreview/Note.png
===================================================================
--- trunk/SkimQuickLookPreview/Note.png 2026-05-14 16:33:34 UTC (rev 16294)
+++ trunk/SkimQuickLookPreview/Note.png 2026-05-23 16:24:47 UTC (rev 16295)

Property changes on: trunk/SkimQuickLookPreview/Note.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/SKPreviewProvider.h
===================================================================
--- trunk/SkimQuickLookPreview/SKPreviewProvider.h                              
(rev 0)
+++ trunk/SkimQuickLookPreview/SKPreviewProvider.h      2026-05-23 16:24:47 UTC 
(rev 16295)
@@ -0,0 +1,44 @@
+//
+//  SKPreviewProvider.h
+//  SkimQuickLookPreview
+//
+//  Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2026
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <Quartz/Quartz.h>
+
+@interface SKPreviewProvider : QLPreviewProvider <QLPreviewingController>
+
+@end

Added: trunk/SkimQuickLookPreview/SKPreviewProvider.m
===================================================================
--- trunk/SkimQuickLookPreview/SKPreviewProvider.m                              
(rev 0)
+++ trunk/SkimQuickLookPreview/SKPreviewProvider.m      2026-05-23 16:24:47 UTC 
(rev 16295)
@@ -0,0 +1,133 @@
+//
+//  SKPreviewProvider.m
+//  SkimQuickLookPreview
+//
+//  Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2026
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SKPreviewProvider.h"
+#import "SKQLConverter.h"
+
+@implementation SKPreviewProvider
+
+/*
+
+ Use a QLPreviewProvider to provide data-based previews.
+ 
+ To set up your extension as a data-based preview extension:
+
+ - Modify the extension's Info.plist by setting
+   <key>QLIsDataBasedPreview</key>
+   <true/>
+ 
+ - Add the supported content types to QLSupportedContentTypes array in the 
extension's Info.plist.
+
+ - Change the NSExtensionPrincipalClass to this class.
+   e.g.
+   <key>NSExtensionPrincipalClass</key>
+   <string>PreviewProvider</string>
+ 
+ - Implement providePreviewForFileRequest:completionHandler:
+ 
+ */
+
+- (void)providePreviewForFileRequest:(QLFilePreviewRequest *)request 
completionHandler:(void (^)(QLPreviewReply *reply, NSError *error))handler
+{
+    NSURL *fileURL = [request fileURL];
+    UTType *fileType = nil;
+    QLPreviewReply *reply = nil;
+    
+    [fileURL getResourceValue:&fileType forKey:NSURLContentTypeKey error:NULL];
+    
+    if ([fileType conformsToType:[UTType 
typeWithIdentifier:@"net.sourceforge.skim-app.pdfd"]]) {
+        
+        NSURL *pdfURL = SKQLPDFURLForPDFBundleURL(fileURL);
+        if (pdfURL)
+            reply = [[QLPreviewReply alloc] initWithFileURL:pdfURL];
+        
+    } else if ([fileType conformsToType:[UTType 
typeWithIdentifier:@"net.sourceforge.skim-app.skimnotes"]]) {
+        
+        reply = [[QLPreviewReply alloc] initWithDataOfContentType:UTTypeHTML 
contentSize:CGSizeMake(800, 800) dataCreationBlock:^NSData *(QLPreviewReply 
*replyToUpdate, NSError **error) {
+            NSData *data = [[NSData alloc] initWithContentsOfURL:fileURL 
options:NSDataReadingUncached error:NULL];
+            if (data) {
+                NSArray *notes = [SKQLConverter notesWithData:data];
+                NSString *htmlString = [SKQLConverter 
htmlStringWithNotes:notes];
+                if ((data = [htmlString 
dataUsingEncoding:NSUTF8StringEncoding])) {
+                    NSSet *types = [NSSet setWithArray:[notes 
valueForKey:@"type"]];
+                    NSMutableDictionary *attachments = [NSMutableDictionary 
dictionary];
+                    NSBundle *bundle = [NSBundle 
bundleForClass:[SKPreviewProvider class]];
+                    for (NSString *type in types) {
+                        NSURL *imageURL = [bundle URLForImageResource:type];
+                        if (imageURL) {
+                            NSData *imageData = [NSData 
dataWithContentsOfURL:imageURL];
+                            if (imageData) {
+                                QLPreviewReplyAttachment *attachment = 
[[QLPreviewReplyAttachment alloc] initWithData:imageData contentType:UTTypePNG];
+                                [attachments setObject:attachment forKey:type];
+                            }
+                        }
+                    }
+                    [replyToUpdate setAttachments:attachments];
+                    [replyToUpdate setStringEncoding:NSUTF8StringEncoding];
+                    return data;
+                }
+            }
+            return nil;
+        }];
+        
+    } else if ([fileType conformsToType:[UTType 
typeWithIdentifier:@"com.adobe.postscript"]]) {
+        
+        if (@available(macOS 14.0, *)) {} else {
+            reply = [[QLPreviewReply alloc] 
initWithDataOfContentType:UTTypePDF contentSize:CGSizeMake(800, 800) 
dataCreationBlock:^NSData *(QLPreviewReply *replyToUpdate, NSError **error) {
+                bool converted = false;
+                CGPSConverterCallbacks converterCallbacks = { 0, NULL, NULL, 
NULL, NULL, NULL, NULL, NULL };
+                CGPSConverterRef converter = CGPSConverterCreate(NULL, 
&converterCallbacks, NULL);
+                CGDataProviderRef provider = 
CGDataProviderCreateWithURL((__bridge CFURLRef)fileURL);
+                CFMutableDataRef data = CFDataCreateMutable(NULL, 0);
+                CGDataConsumerRef consumer = 
CGDataConsumerCreateWithCFData(data);
+                if (provider != NULL && consumer != NULL)
+                    converted = CGPSConverterConvert(converter, provider, 
consumer, NULL);
+                CGDataProviderRelease(provider);
+                CGDataConsumerRelease(consumer);
+                CFRelease(converter);
+                
+                return converted ? CFBridgingRelease(data) : nil;
+            }];
+        }
+    }
+
+    handler(reply, nil);
+}
+
+@end
+

Added: trunk/SkimQuickLookPreview/SKQLConverter.h
===================================================================
--- trunk/SkimQuickLookPreview/SKQLConverter.h                          (rev 0)
+++ trunk/SkimQuickLookPreview/SKQLConverter.h  2026-05-23 16:24:47 UTC (rev 
16295)
@@ -0,0 +1,47 @@
+//
+//  SKQLConverter.h
+//  SkimQuickLookPreview
+//
+//  Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2007
+ Christiaan Hofman. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+NSURL *SKQLPDFURLForPDFBundleURL(NSURL *url);
+
+@interface SKQLConverter : NSObject
++ (NSArray *)notesWithData:(NSData *)data;
++ (NSAttributedString *)attributedStringWithNotes:(NSArray *)notes 
bundle:(NSBundle *)bundle;
++ (NSString *)htmlStringWithNotes:(NSArray *)notes;
+@end

Added: trunk/SkimQuickLookPreview/SKQLConverter.m
===================================================================
--- trunk/SkimQuickLookPreview/SKQLConverter.m                          (rev 0)
+++ trunk/SkimQuickLookPreview/SKQLConverter.m  2026-05-23 16:24:47 UTC (rev 
16295)
@@ -0,0 +1,270 @@
+//
+//  SKQLConverter.h
+//  SkimQuickLookPreview
+//
+//  Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2007
+ Christiaan Hofman. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SKQLConverter.h"
+#include <tgmath.h>
+
+static NSString *_noteFontName = @"LucidaHandwriting-Italic";
+static const CGFloat _noteIndent = 20.0;
+// readable in Cover Flow view, and distinguishable as text in icon view
+static const CGFloat _fontSize = 20.0;
+static const CGFloat _smallFontSize = 10.0;
+
+NSURL *SKQLPDFURLForPDFBundleURL(NSURL *url)
+{
+    NSString *filePath = [url path];
+    NSArray *files = [[NSFileManager defaultManager] subpathsAtPath:filePath];
+    NSString *fileName = [[[filePath lastPathComponent] 
stringByDeletingPathExtension] stringByAppendingPathExtension:@"pdf"];
+    NSString *pdfFile = nil;
+    
+    if ([files containsObject:fileName]) {
+        pdfFile = fileName;
+    } else {
+        NSUInteger idx = [[files 
valueForKeyPath:@"pathExtension.lowercaseString"] indexOfObject:@"pdf"];
+        if (idx != NSNotFound)
+            pdfFile = [files objectAtIndex:idx];
+    }
+    return pdfFile ? [url URLByAppendingPathComponent:pdfFile] : nil;
+}
+
+static NSAttributedString *imageAttachmentForType(NSString *type, NSBundle 
*bundle)
+{
+    static NSMutableDictionary *imageWrappers = nil;
+    NSFileWrapper *wrapper = [imageWrappers objectForKey:type];
+    
+    if (wrapper == nil) {
+        NSURL *imgURL = [bundle URLForImageResource:type];
+        if (imageWrappers == nil)
+            imageWrappers = [[NSMutableDictionary alloc] init];
+        wrapper = [[NSFileWrapper alloc] initWithURL:imgURL options:0 
error:NULL];
+        [wrapper setPreferredFilename:[type 
stringByAppendingPathExtension:@"png"]];
+        [imageWrappers setObject:wrapper forKey:type];
+    }
+    
+    NSTextAttachment *attachment = [[NSTextAttachment alloc] 
initWithFileWrapper:wrapper];
+    NSAttributedString *attrString = [NSAttributedString 
attributedStringWithAttachment:attachment];
+    
+    return attrString;
+}
+
+static NSColor *colorFromArray(NSArray *array) {
+    CGFloat c[4] = {0.0, 0.0, 0.0, 1.0};
+    if ([array count] > 2) {
+        NSUInteger i;
+        for (i = 0; i < MAX([array count], 4); i++)
+            c[i] = [[array objectAtIndex:i] doubleValue];
+    } else if ([array count] > 0) {
+        c[0] = c[1] = c[2] = [[array objectAtIndex:0] doubleValue];
+        if ([array count] == 2)
+            c[3] = [[array objectAtIndex:1] doubleValue];
+    }
+    return [NSColor colorWithColorSpace:[NSColorSpace sRGBColorSpace] 
components:c count:4];
+}
+
+static NSString *hexStringWithColor(NSColor *color)
+{
+    if ([color alphaComponent] < 1.0)
+        color = [[NSColor whiteColor] blendedColorWithFraction:[color 
alphaComponent] ofColor:[color colorWithAlphaComponent:1.0]];
+    color = [color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]];
+    unsigned int red = (unsigned int)round(255 * [color redComponent]);
+    unsigned int green = (unsigned int)round(255 * [color greenComponent]);
+    unsigned int blue = (unsigned int)round(255 * [color blueComponent]);
+    return [NSString stringWithFormat:@"%.2x%.2x%.2x", red, green, blue];
+}
+
+// Stolen from OmniFoundation; modified to use malloc instead of alloca()
+static NSString *HTMLEscapeString(NSString *htmlString)
+{
+    unichar *ptr, *begin, *end;
+    NSMutableString *result;
+    NSInteger length;
+    
+#define APPEND_PREVIOUS() \
+    [result appendString:[[NSString alloc] initWithCharacters:begin 
length:(ptr - begin)]]; \
+    begin = ptr + 1;
+    
+    length = [htmlString length];
+    ptr = malloc(length * sizeof(unichar));
+    if (!ptr)
+        return nil;
+    
+    // keep a pointer that we can free later
+    unichar *originalPtr = ptr;
+
+    end = ptr + length;
+    [htmlString getCharacters:ptr];
+    result = [NSMutableString stringWithCapacity:length];
+    
+    begin = ptr;
+    while (ptr < end) {
+        if (*ptr > 127) {
+            APPEND_PREVIOUS();
+            [result appendFormat:@"&#%ld;", (long)*ptr];
+        } else if (*ptr == '&') {
+            APPEND_PREVIOUS();
+            [result appendString:@"&amp;"];
+        } else if (*ptr == '\"') {
+            APPEND_PREVIOUS();
+            [result appendString:@"&quot;"];
+        } else if (*ptr == '<') {
+             APPEND_PREVIOUS();
+            [result appendString:@"&lt;"];
+        } else if (*ptr == '>') {
+            APPEND_PREVIOUS();
+            [result appendString:@"&gt;"];
+        } else if (*ptr == '\r') {
+            APPEND_PREVIOUS();
+            if (ptr+1 == end || *(ptr+1) != '\n')
+                [result appendString:@"<br />"];
+        } else if (*ptr == '\n') {
+            APPEND_PREVIOUS();
+            [result appendString:@"<br />"];
+        }
+        ptr++;
+    }
+    APPEND_PREVIOUS();
+    free(originalPtr);
+    return result;
+}
+
+@implementation SKQLConverter
+
++ (NSArray *)notesWithData:(NSData *)data;
+{
+    NSArray *notes = nil;
+    unsigned char ch = 0;
+    if ([data length] > 8)
+        [data getBytes:&ch range:NSMakeRange(8, 1)];
+    ch >>= 4;
+    if (ch == 0xD) {
+        @try { notes = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet 
setWithObjects:[NSArray class], [NSDictionary class], [NSString class], 
[NSNumber class], [NSData class], [NSDate class], [NSColor class], [NSFont 
class], [NSAttributedString class], [NSImage class], nil] fromData:data 
error:NULL];; }
+        @catch (id e) {}
+    } else {
+        notes = [NSPropertyListSerialization propertyListWithData:data 
options:NSPropertyListImmutable format:NULL error:NULL];
+    }
+    return [notes isKindOfClass:[NSArray class]] ? notes : nil;
+}
+
++ (NSAttributedString *)attributedStringWithNotes:(NSArray *)notes 
bundle:(NSBundle *)bundle;
+{
+    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] 
init];
+    NSFont *font = [NSFont userFontOfSize:_fontSize];
+    NSFont *noteFont = [NSFont fontWithName:_noteFontName size:_fontSize];
+    NSFont *noteTextFont = [NSFont fontWithName:_noteFontName 
size:_smallFontSize];
+    NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:font, 
NSFontAttributeName, nil];
+    NSDictionary *noteAttrs = [NSDictionary 
dictionaryWithObjectsAndKeys:noteFont, NSFontAttributeName, [NSParagraphStyle 
defaultParagraphStyle], NSParagraphStyleAttributeName, nil];
+    NSDictionary *noteTextAttrs = [NSDictionary 
dictionaryWithObjectsAndKeys:noteTextFont, NSFontAttributeName, 
[NSParagraphStyle defaultParagraphStyle], NSParagraphStyleAttributeName, nil];
+    NSMutableParagraphStyle *noteParStyle = [[NSParagraphStyle 
defaultParagraphStyle] mutableCopy];
+    
+    [noteParStyle setFirstLineHeadIndent:_noteIndent];
+    [noteParStyle setHeadIndent:_noteIndent];
+    
+    if (notes) {
+        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
initWithKey:@"pageIndex" ascending:YES];
+        NSEnumerator *noteEnum = [[notes sortedArrayUsingDescriptors:[NSArray 
arrayWithObject:sortDescriptor]] objectEnumerator];
+        NSDictionary *note;
+        while (note = [noteEnum nextObject]) {
+            NSString *type = [note objectForKey:@"type"];
+            NSString *contents = [note objectForKey:@"contents"];
+            NSAttributedString *text = [note objectForKey:@"text"];
+            NSColor *color = [note objectForKey:@"color"];
+            NSUInteger pageIndex = [[note objectForKey:@"pageIndex"] 
unsignedIntegerValue];
+            NSInteger start;
+            
+            if ([text isKindOfClass:[NSData class]])
+                text = [[NSAttributedString alloc] initWithData:(NSData *)text 
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL];
+            if ([color isKindOfClass:[NSArray class]])
+                color = colorFromArray((NSArray *)color);
+            
+            [attrString appendAttributedString:imageAttachmentForType(type, 
bundle)];
+            [attrString addAttribute:NSBackgroundColorAttributeName 
value:color range:NSMakeRange([attrString length] - 1, 1)];
+            [attrString appendAttributedString:[[NSAttributedString alloc] 
initWithString:[NSString stringWithFormat:@"%@ (page %ld)\n", type, 
(long)(pageIndex+1)] attributes:attrs]];
+            start = [attrString length];
+            [attrString appendAttributedString:[[NSAttributedString alloc] 
initWithString:contents attributes:noteAttrs]];
+            if (text) {
+                [attrString appendAttributedString:[[NSAttributedString alloc] 
initWithString:@"\n"]];
+                [attrString appendAttributedString:[[NSAttributedString alloc] 
initWithString:[text string] attributes:noteTextAttrs]];
+            }
+            [attrString appendAttributedString:[[NSAttributedString alloc] 
initWithString:@"\n"]];
+            [attrString addAttribute:NSParagraphStyleAttributeName 
value:noteParStyle range:NSMakeRange(start, [attrString length] - start)];
+        }
+        [attrString fixAttributesInRange:NSMakeRange(0, [attrString length])];
+    }
+    
+    return attrString;
+}
+
++ (NSString *)htmlStringWithNotes:(NSArray *)notes;
+{
+    NSMutableString *htmlString = [NSMutableString string];
+    [htmlString appendString:@"<html><head><style type=\"text/css\">"];
+    [htmlString appendString:@"body {font-family:Helvetica} "];
+    [htmlString appendString:@"dd {font-style:italic} "];
+    [htmlString appendString:@".note-text {font-size:smaller} "];
+    [htmlString appendString:@"</style></head><body><dl>"];
+    
+    if (notes) {
+        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
initWithKey:@"pageIndex" ascending:YES];
+        NSEnumerator *noteEnum = [[notes sortedArrayUsingDescriptors:[NSArray 
arrayWithObject:sortDescriptor]] objectEnumerator];
+        NSDictionary *note;
+        while (note = [noteEnum nextObject]) {
+            NSString *type = [note objectForKey:@"type"];
+            NSString *contents = [note objectForKey:@"contents"];
+            NSAttributedString *text = [note objectForKey:@"text"];
+            NSColor *color = [note objectForKey:@"color"];
+            NSUInteger pageIndex = [[note objectForKey:@"pageIndex"] 
unsignedIntegerValue];
+            
+            if ([text isKindOfClass:[NSData class]])
+                text = [[NSAttributedString alloc] initWithData:(NSData *)text 
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL];
+            if ([color isKindOfClass:[NSArray class]])
+                color = colorFromArray((NSArray *)color);
+            
+            [htmlString appendFormat:@"<dt><img src=\"cid:%@.png\" 
style=\"background-color:#%@\" />%@ (page %ld)</dt>", type, 
hexStringWithColor(color), type, (long)(pageIndex+1)];
+            [htmlString appendFormat:@"<dd>%@", HTMLEscapeString(contents)];
+            if (text)
+                [htmlString appendFormat:@"<div class=\"note-text\">%@</div>", 
HTMLEscapeString([text string])];
+            [htmlString appendString:@"</dd>"];
+        }
+    }
+    
+    [htmlString appendString:@"</dl></body></html>"];
+    
+    return htmlString;
+}
+
+@end

Added: trunk/SkimQuickLookPreview/SkimQuickLookPreview.entitlements
===================================================================
--- trunk/SkimQuickLookPreview/SkimQuickLookPreview.entitlements                
                (rev 0)
+++ trunk/SkimQuickLookPreview/SkimQuickLookPreview.entitlements        
2026-05-23 16:24:47 UTC (rev 16295)
@@ -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.app-sandbox</key>
+    <true/>
+    <key>com.apple.security.files.user-selected.read-only</key>
+    <true/>
+</dict>
+</plist>

Added: trunk/SkimQuickLookPreview/Square.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookPreview/Square.png
===================================================================
--- trunk/SkimQuickLookPreview/Square.png       2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookPreview/Square.png       2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookPreview/Square.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/StrikeOut.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookPreview/StrikeOut.png
===================================================================
--- trunk/SkimQuickLookPreview/StrikeOut.png    2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookPreview/StrikeOut.png    2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookPreview/StrikeOut.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Underline.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookPreview/Underline.png
===================================================================
--- trunk/SkimQuickLookPreview/Underline.png    2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookPreview/Underline.png    2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookPreview/Underline.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookPreview/Widget.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookPreview/Widget.png
===================================================================
--- trunk/SkimQuickLookPreview/Widget.png       2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookPreview/Widget.png       2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookPreview/Widget.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/Circle.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookThumbnails/Circle.png
===================================================================
--- trunk/SkimQuickLookThumbnails/Circle.png    2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookThumbnails/Circle.png    2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookThumbnails/Circle.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/FreeText.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookThumbnails/FreeText.png
===================================================================
--- trunk/SkimQuickLookThumbnails/FreeText.png  2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookThumbnails/FreeText.png  2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookThumbnails/FreeText.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/Highlight.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookThumbnails/Highlight.png
===================================================================
--- trunk/SkimQuickLookThumbnails/Highlight.png 2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookThumbnails/Highlight.png 2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookThumbnails/Highlight.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/Info.plist
===================================================================
--- trunk/SkimQuickLookThumbnails/Info.plist                            (rev 0)
+++ trunk/SkimQuickLookThumbnails/Info.plist    2026-05-23 16:24:47 UTC (rev 
16295)
@@ -0,0 +1,87 @@
+<?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>QLSupportedContentTypes</key>
+                       <array>
+                               <string>net.sourceforge.skim-app.pdfd</string>
+                               
<string>net.sourceforge.skim-app.skimnotes</string>
+                               <string>com.adobe.postscript</string>
+                       </array>
+                       <key>QLThumbnailMinimumDimension</key>
+                       <integer>0</integer>
+               </dict>
+               <key>NSExtensionPointIdentifier</key>
+               <string>com.apple.quicklook.thumbnail</string>
+               <key>NSExtensionPrincipalClass</key>
+               <string>SKThumbnailProvider</string>
+       </dict>
+       <key>UTImportedTypeDeclarations</key>
+       <array>
+               <dict>
+                       <key>UTTypeConformsTo</key>
+                       <array>
+                               <string>com.apple.package</string>
+                               <string>public.composite-content</string>
+                       </array>
+                       <key>UTTypeDescription</key>
+                       <string>PDF Bundle</string>
+                       <key>UTTypeIdentifier</key>
+                       <string>net.sourceforge.skim-app.pdfd</string>
+                       <key>UTTypeTagSpecification</key>
+                       <dict>
+                               <key>com.apple.ostype</key>
+                               <string>PDFD</string>
+                               <key>public.filename-extension</key>
+                               <array>
+                                       <string>pdfd</string>
+                               </array>
+                       </dict>
+               </dict>
+               <dict>
+                       <key>UTTypeConformsTo</key>
+                       <array>
+                               <string>public.data</string>
+                       </array>
+                       <key>UTTypeDescription</key>
+                       <string>Skim Notes</string>
+                       <key>UTTypeIdentifier</key>
+                       <string>net.sourceforge.skim-app.skimnotes</string>
+                       <key>UTTypeTagSpecification</key>
+                       <dict>
+                               <key>com.apple.ostype</key>
+                               <string>SKNT</string>
+                               <key>public.filename-extension</key>
+                               <array>
+                                       <string>skim</string>
+                               </array>
+                       </dict>
+               </dict>
+               <dict>
+                       <key>UTTypeConformsTo</key>
+                       <array>
+                               <string>public.data</string>
+                       </array>
+                       <key>UTTypeDescription</key>
+                       <string>PostScript</string>
+                       <key>UTTypeIdentifier</key>
+                       <string>com.adobe.postscript</string>
+                       <key>UTTypeTagSpecification</key>
+                       <dict>
+                               <key>public.filename-extension</key>
+                               <array>
+                                       <string>ps</string>
+                               </array>
+                               <key>public.mime-type</key>
+                               <array>
+                                       <string>application/postscript</string>
+                               </array>
+                       </dict>
+               </dict>
+       </array>
+</dict>
+</plist>

Added: trunk/SkimQuickLookThumbnails/Ink.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookThumbnails/Ink.png
===================================================================
--- trunk/SkimQuickLookThumbnails/Ink.png       2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookThumbnails/Ink.png       2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookThumbnails/Ink.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/Line.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookThumbnails/Line.png
===================================================================
--- trunk/SkimQuickLookThumbnails/Line.png      2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookThumbnails/Line.png      2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookThumbnails/Line.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/Note.png
===================================================================
(Binary files differ)

Index: trunk/SkimQuickLookThumbnails/Note.png
===================================================================
--- trunk/SkimQuickLookThumbnails/Note.png      2026-05-14 16:33:34 UTC (rev 
16294)
+++ trunk/SkimQuickLookThumbnails/Note.png      2026-05-23 16:24:47 UTC (rev 
16295)

Property changes on: trunk/SkimQuickLookThumbnails/Note.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: trunk/SkimQuickLookThumbnails/SKQLConverter.h
===================================================================
--- trunk/SkimQuickLookThumbnails/SKQLConverter.h                               
(rev 0)
+++ trunk/SkimQuickLookThumbnails/SKQLConverter.h       2026-05-23 16:24:47 UTC 
(rev 16295)
@@ -0,0 +1,47 @@
+//
+//  SKQLConverter.h
+//  SkimQuickLookThumbnails
+//
+//  Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2007
+ Christiaan Hofman. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+extern NSURL *SKQLPDFURLForPDFBundleURL(NSURL *url);
+
+@interface SKQLConverter : NSObject
++ (NSArray *)notesWithData:(NSData *)data;
++ (NSAttributedString *)attributedStringWithNotes:(NSArray *)notes 
bundle:(NSBundle *)bundle;
++ (NSString *)htmlStringWithNotes:(NSArray *)notes;
+@end

Added: trunk/SkimQuickLookThumbnails/SKQLConverter.m
===================================================================
--- trunk/SkimQuickLookThumbnails/SKQLConverter.m                               
(rev 0)
+++ trunk/SkimQuickLookThumbnails/SKQLConverter.m       2026-05-23 16:24:47 UTC 
(rev 16295)
@@ -0,0 +1,270 @@
+//
+//  SKQLConverter.h
+//  SkimQuickLookThumbnails
+//
+//  Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2007
+ Christiaan Hofman. All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 
+ - Neither the name of Christiaan Hofman nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ 
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SKQLConverter.h"
+#include <tgmath.h>
+
+static NSString *_noteFontName = @"LucidaHandwriting-Italic";
+static const CGFloat _noteIndent = 20.0;
+// readable in Cover Flow view, and distinguishable as text in icon view
+static const CGFloat _fontSize = 20.0;
+static const CGFloat _smallFontSize = 10.0;
+
+NSURL *SKQLPDFURLForPDFBundleURL(NSURL *url)
+{
+    NSString *filePath = [url path];
+    NSArray *files = [[NSFileManager defaultManager] subpathsAtPath:filePath];
+    NSString *fileName = [[[filePath lastPathComponent] 
stringByDeletingPathExtension] stringByAppendingPathExtension:@"pdf"];
+    NSString *pdfFile = nil;
+    
+    if ([files containsObject:fileName]) {
+        pdfFile = fileName;
+    } else {
+        NSUInteger idx = [[files 
valueForKeyPath:@"pathExtension.lowercaseString"] indexOfObject:@"pdf"];
+        if (idx != NSNotFound)
+            pdfFile = [files objectAtIndex:idx];
+    }
+    return pdfFile ? [url URLByAppendingPathComponent:pdfFile] : nil;
+}
+
+static NSAttributedString *imageAttachmentForType(NSString *type, NSBundle 
*bundle)
+{
+    static NSMutableDictionary *imageWrappers = nil;
+    NSFileWrapper *wrapper = [imageWrappers objectForKey:type];
+    
+    if (wrapper == nil) {
+        NSURL *imgURL = [bundle URLForImageResource:type];
+        if (imageWrappers == nil)
+            imageWrappers = [[NSMutableDictionary alloc] init];
+        wrapper = [[NSFileWrapper alloc] initWithURL:imgURL options:0 
error:NULL];
+        [wrapper setPreferredFilename:[type 
stringByAppendingPathExtension:@"png"]];
+        [imageWrappers setObject:wrapper forKey:type];
+    }
+    
+    NSTextAttachment *attachment = [[NSTextAttachment alloc] 
initWithFileWrapper:wrapper];
+    NSAttributedString *attrString = [NSAttributedString 
attributedStringWithAttachment:attachment];
+    
+    return attrString;
+}
+
+static NSColor *colorFromArray(NSArray *array) {
+    CGFloat c[4] = {0.0, 0.0, 0.0, 1.0};
+    if ([array count] > 2) {
+        NSUInteger i;
+        for (i = 0; i < MAX([array count], 4); i++)
+            c[i] = [[array objectAtIndex:i] doubleValue];
+    } else if ([array count] > 0) {
+        c[0] = c[1] = c[2] = [[array objectAtIndex:0] doubleValue];
+        if ([array count] == 2)
+            c[3] = [[array objectAtIndex:1] doubleValue];
+    }
+    return [NSColor colorWithColorSpace:[NSColorSpace sRGBColorSpace] 
components:c count:4];
+}
+
+static NSString *hexStringWithColor(NSColor *color)
+{
+    if ([color alphaComponent] < 1.0)
+        color = [[NSColor whiteColor] blendedColorWithFraction:[color 
alphaComponent] ofColor:[color colorWithAlphaComponent:1.0]];
+    color = [color colorUsingColorSpace:[NSColorSpace sRGBColorSpace]];
+    unsigned int red = (unsigned int)round(255 * [color redComponent]);
+    unsigned int green = (unsigned int)round(255 * [color greenComponent]);
+    unsigned int blue = (unsigned int)round(255 * [color blueComponent]);
+    return [NSString stringWithFormat:@"%.2x%.2x%.2x", red, green, blue];
+}
+
+// Stolen from OmniFoundation; modified to use malloc instead of alloca()
+static NSString *HTMLEscapeString(NSString *htmlString)
+{
+    unichar *ptr, *begin, *end;
+    NSMutableString *result;
+    NSInteger length;
+    
+#define APPEND_PREVIOUS() \
+    [result appendString:[[NSString alloc] initWithCharacters:begin 
length:(ptr - begin)]]; \
+    begin = ptr + 1;
+    
+    length = [htmlString length];
+    ptr = malloc(length * sizeof(unichar));
+    if (!ptr)
+        return nil;
+    
+    // keep a pointer that we can free later
+    unichar *originalPtr = ptr;
+
+    end = ptr + length;
+    [htmlString getCharacters:ptr];
+    result = [NSMutableString stringWithCapacity:length];
+    
+    begin = ptr;
+    while (ptr < end) {
+        if (*ptr > 127) {
+            APPEND_PREVIOUS();
+            [result appendFormat:@"&#%ld;", (long)*ptr];
+        } else if (*ptr == '&') {
+            APPEND_PREVIOUS();
+            [result appendString:@"&amp;"];
+        } else if (*ptr == '\"') {
+            APPEND_PREVIOUS();
+            [result appendString:@"&quot;"];
+        } else if (*ptr == '<') {
+             APPEND_PREVIOUS();
+            [result appendString:@"&lt;"];
+        } else if (*ptr == '>') {
+            APPEND_PREVIOUS();
+            [result appendString:@"&gt;"];
+        } else if (*ptr == '\r') {
+            APPEND_PREVIOUS();
+            if (ptr+1 == end || *(ptr+1) != '\n')
+                [result appendString:@"<br />"];
+        } else if (*ptr == '\n') {
+            APPEND_PREVIOUS();
+            [result appendString:@"<br />"];
+        }
+        ptr++;
+    }
+    APPEND_PREVIOUS();
+    free(originalPtr);
+    return result;
+}
+
+@implementation SKQLConverter
+
++ (NSArray *)notesWithData:(NSData *)data;
+{
+    NSArray *notes = nil;
+    unsigned char ch = 0;
+    if ([data length] > 8)
+        [data getBytes:&ch range:NSMakeRange(8, 1)];
+    ch >>= 4;
+    if (ch == 0xD) {
+        @try { notes = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet 
setWithObjects:[NSArray class], [NSDictionary class], [NSString class], 
[NSNumber class], [NSData class], [NSDate class], [NSColor class], [NSFont 
class], [NSAttributedString class], [NSImage class], nil] fromData:data 
error:NULL];; }
+        @catch (id e) {}
+    } else {
+        notes = [NSPropertyListSerialization propertyListWithData:data 
options:NSPropertyListImmutable format:NULL error:NULL];
+    }
+    return [notes isKindOfClass:[NSArray class]] ? notes : nil;
+}
+
++ (NSAttributedString *)attributedStringWithNotes:(NSArray *)notes 
bundle:(NSBundle *)bundle;
+{
+    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] 
init];
+    NSFont *font = [NSFont userFontOfSize:_fontSize];
+    NSFont *noteFont = [NSFont fontWithName:_noteFontName size:_fontSize];
+    NSFont *noteTextFont = [NSFont fontWithName:_noteFontName 
size:_smallFontSize];
+    NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:font, 
NSFontAttributeName, nil];
+    NSDictionary *noteAttrs = [NSDictionary 
dictionaryWithObjectsAndKeys:noteFont, NSFontAttributeName, [NSParagraphStyle 
defaultParagraphStyle], NSParagraphStyleAttributeName, nil];
+    NSDictionary *noteTextAttrs = [NSDictionary 
dictionaryWithObjectsAndKeys:noteTextFont, NSFontAttributeName, 
[NSParagraphStyle defaultParagraphStyle], NSParagraphStyleAttributeName, nil];
+    NSMutableParagraphStyle *noteParStyle = [[NSParagraphStyle 
defaultParagraphStyle] mutableCopy];
+    
+    [noteParStyle setFirstLineHeadIndent:_noteIndent];
+    [noteParStyle setHeadIndent:_noteIndent];
+    
+    if (notes) {
+        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
initWithKey:@"pageIndex" ascending:YES];
+        NSEnumerator *noteEnum = [[notes sortedArrayUsingDescriptors:[NSArray 
arrayWithObject:sortDescriptor]] objectEnumerator];
+        NSDictionary *note;
+        while (note = [noteEnum nextObject]) {
+            NSString *type = [note objectForKey:@"type"];
+            NSString *contents = [note objectForKey:@"contents"];
+            NSAttributedString *text = [note objectForKey:@"text"];
+            NSColor *color = [note objectForKey:@"color"];
+            NSUInteger pageIndex = [[note objectForKey:@"pageIndex"] 
unsignedIntegerValue];
+            NSInteger start;
+            
+            if ([text isKindOfClass:[NSData class]])
+                text = [[NSAttributedString alloc] initWithData:(NSData *)text 
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL];
+            if ([color isKindOfClass:[NSArray class]])
+                color = colorFromArray((NSArray *)color);
+            
+            [attrString appendAttributedString:imageAttachmentForType(type, 
bundle)];
+            [attrString addAttribute:NSBackgroundColorAttributeName 
value:color range:NSMakeRange([attrString length] - 1, 1)];
+            [attrString appendAttributedString:[[NSAttributedString alloc] 
initWithString:[NSString stringWithFormat:@"%@ (page %ld)\n", type, 
(long)(pageIndex+1)] attributes:attrs]];
+            start = [attrString length];
+            [attrString appendAttributedString:[[NSAttributedString alloc] 
initWithString:contents attributes:noteAttrs]];
+            if (text) {
+                [attrString appendAttributedString:[[NSAttributedString alloc] 
initWithString:@"\n"]];
+                [attrString appendAttributedString:[[NSAttributedString alloc] 
initWithString:[text string] attributes:noteTextAttrs]];
+            }
+            [attrString appendAttributedString:[[NSAttributedString alloc] 
initWithString:@"\n"]];
+            [attrString addAttribute:NSParagraphStyleAttributeName 
value:noteParStyle range:NSMakeRange(start, [attrString length] - start)];
+        }
+        [attrString fixAttributesInRange:NSMakeRange(0, [attrString length])];
+    }
+    
+    return attrString;
+}
+
++ (NSString *)htmlStringWithNotes:(NSArray *)notes;
+{
+    NSMutableString *htmlString = [NSMutableString string];
+    [htmlString appendString:@"<html><head><style type=\"text/css\">"];
+    [htmlString appendString:@"body {font-family:Helvetica} "];
+    [htmlString appendString:@"dd {font-style:italic} "];
+    [htmlString appendString:@".note-text {font-size:smaller} "];
+    [htmlString appendString:@"</style></head><body><dl>"];
+    
+    if (notes) {
+        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
initWithKey:@"pageIndex" ascending:YES];
+        NSEnumerator *noteEnum = [[notes sortedArrayUsingDescriptors:[NSArray 
arrayWithObject:sortDescriptor]] objectEnumerator];
+        NSDictionary *note;
+        while (note = [noteEnum nextObject]) {
+            NSString *type = [note objectForKey:@"type"];
+            NSString *contents = [note objectForKey:@"contents"];
+            NSAttributedString *text = [note objectForKey:@"text"];
+            NSColor *color = [note objectForKey:@"color"];
+            NSUInteger pageIndex = [[note objectForKey:@"pageIndex"] 
unsignedIntegerValue];
+            
+            if ([text isKindOfClass:[NSData class]])
+                text = [[NSAttributedString alloc] initWithData:(NSData *)text 
options:[NSDictionary dictionary] documentAttributes:NULL error:NULL];
+            if ([color isKindOfClass:[NSArray class]])
+                color = colorFromArray((NSArray *)color);
+            
+            [htmlString appendFormat:@"<dt><img src=\"cid:%@.png\" 
style=\"background-color:#%@\" />%@ (page %ld)</dt>", type, 
hexStringWithColor(color), type, (long)(pageIndex+1)];
+            [htmlString appendFormat:@"<dd>%@", HTMLEscapeString(contents)];
+            if (text)
+                [htmlString appendFormat:@"<div class=\"note-text\">%@</div>", 
HTMLEscapeString([text string])];
+            [htmlString appendString:@"</dd>"];
+        }
+    }
+    
+    [htmlString appendString:@"</dl></body></html>"];
+    
+    return htmlString;
+}
+
+@end

Added: trunk/SkimQuickLookThumbnails/SKThumbnailProvider.h
===================================================================
--- trunk/SkimQuickLookThumbnails/SKThumbnailProvider.h                         
(rev 0)
+++ trunk/SkimQuickLookThumbnails/SKThumbnailProvider.h 2026-05-23 16:24:47 UTC 
(rev 16295)
@@ -0,0 +1,47 @@
+//
+//  SKThumbnailProvider.h
+//  SkimQuickLookThumbnails
+//
+//  Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2026
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <QuickLookThumbnailing/QuickLookThumbnailing.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SKThumbnailProvider : QLThumbnailProvider
+
+@end
+
+NS_ASSUME_NONNULL_END

Added: trunk/SkimQuickLookThumbnails/SKThumbnailProvider.m
===================================================================
--- trunk/SkimQuickLookThumbnails/SKThumbnailProvider.m                         
(rev 0)
+++ trunk/SkimQuickLookThumbnails/SKThumbnailProvider.m 2026-05-23 16:24:47 UTC 
(rev 16295)
@@ -0,0 +1,247 @@
+//
+//  SKThumbnailProvider.m
+//  SkimQuickLookThumbnails
+//
+//  Created by Christiaan Hofman on 22/05/2026.
+/*
+ This software is Copyright (c) 2026
+ Christiaan Hofman. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+
+ - Neither the name of Christiaan Hofman nor the names of any
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SKThumbnailProvider.h"
+#import <Cocoa/Cocoa.h>
+#import "SKQLConverter.h"
+
+// Same size as [[NSPrintInfo sharedPrintInfo] paperSize] on my system
+// NSPrintInfo must not be used in a non-main thread (and it's hellishly slow 
in some circumstances)
+static const NSSize _paperSize = (NSSize) { 612, 792 };
+
+// page margins 20 pt on all edges
+static const CGFloat _horizontalMargin = 20;
+static const CGFloat _verticalMargin = 20;
+static const NSSize _containerSize = (NSSize) { 572, 752 };
+static const NSRect _iconRect = (NSRect) { { 50, 140 }, { 512, 512 } };
+
+// wash the app icon over a white page background
+static void drawBackgroundAndApplicationIconInCurrentContext(NSBundle *bundle)
+{
+    [[NSColor whiteColor] setFill];
+    NSRect pageRect = { NSZeroPoint, _paperSize };
+    NSRectFillUsingOperation(pageRect, NSCompositingOperationSourceOver);
+    BOOL isHR = 
CGContextGetUserSpaceToDeviceSpaceTransform([[NSGraphicsContext currentContext] 
CGContext]).a > 1.0;
+    
+    NSURL *iconURL = [bundle URLForImageResource:isHR ? @"Skim_2x" : @"Skim"];
+    NSImage *appIcon = [[NSImage alloc] initWithContentsOfURL:iconURL];
+    
+    [appIcon drawInRect:_iconRect fromRect:NSZeroRect 
operation:NSCompositingOperationSourceOver fraction:0.3];
+}
+
+// creates a new NSTextStorage/NSLayoutManager/NSTextContainer system suitable 
for drawing in a thread
+static NSTextStorage *createTextStorage()
+{
+    NSTextStorage *textStorage = [[NSTextStorage alloc] init];
+    NSLayoutManager *lm = [[NSLayoutManager alloc] init];
+    NSTextContainer *tc = [[NSTextContainer alloc] init];
+    [tc setContainerSize:_containerSize];
+    [lm addTextContainer:tc];
+    // don't let the layout manager use its threaded layout (see header)
+    [lm setBackgroundLayoutEnabled:NO];
+    [textStorage addLayoutManager:lm];
+    // see header; the CircleView example sets it to NO
+    //[lm setUsesScreenFonts:YES];
+
+    return textStorage;
+}
+
+// assumes that the current NSGraphicsContext is the destination
+static void drawAttributedStringInCurrentContext(NSAttributedString 
*attrString)
+{
+    CGContextRef ctxt = [[NSGraphicsContext currentContext] CGContext];
+    
+    NSTextStorage *textStorage = createTextStorage();
+    [textStorage beginEditing];
+    [textStorage setAttributedString:attrString];
+    
+    [textStorage endEditing];
+    NSRect stringRect = NSZeroRect;
+    stringRect.size = _paperSize;
+    
+    CGContextSaveGState(ctxt);
+    
+    CGAffineTransform t1 = CGAffineTransformMakeTranslation(_horizontalMargin, 
_paperSize.height - _verticalMargin);
+    CGAffineTransform t2 = CGAffineTransformMakeScale(1, -1);
+    CGAffineTransform pageTransform = CGAffineTransformConcat(t2, t1);
+    CGContextConcatCTM(ctxt, pageTransform);
+    
+    // objectAtIndex:0 is safe, since we added these to the text storage (so 
there's at least one)
+    NSLayoutManager *lm = [[textStorage layoutManagers] objectAtIndex:0];
+    NSTextContainer *tc = [[lm textContainers] objectAtIndex:0];
+    
+    NSRange glyphRange;
+    
+    // we now have a properly flipped graphics context, so force layout and 
then draw the text
+    glyphRange = [lm glyphRangeForBoundingRect:stringRect inTextContainer:tc];

@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit

Reply via email to