├── AsciiDocQuickLook
├── AsciiDocQuickLook-Bridging-Header.h
├── GeneratePreviewForURL.m
├── Info.plist
├── AsciiDocManager.swift
├── GenerateThumbnailForURL.m
└── main.c
├── AsciiDocQuickLook.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── LICENSE.txt
├── .gitignore
└── README.adoc
/AsciiDocQuickLook/AsciiDocQuickLook-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 |
--------------------------------------------------------------------------------
/AsciiDocQuickLook.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Clyde Clements
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/AsciiDocQuickLook/GeneratePreviewForURL.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 | #import
5 | #import "AsciiDocQuickLook-Swift.h"
6 |
7 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
8 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview);
9 |
10 | /* -----------------------------------------------------------------------------
11 | Generate a preview for file
12 | This function's job is to create preview for designated file
13 | ----------------------------------------------------------------------------- */
14 |
15 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options)
16 | {
17 | if (QLPreviewRequestIsCancelled(preview)) {
18 | return noErr;
19 | }
20 |
21 | AsciiDocManager* adManager = [[AsciiDocManager alloc] initWithUrl:(__bridge NSURL *)url];
22 |
23 | CFDataRef data = (__bridge CFDataRef)[adManager buildPreview];
24 |
25 | if (QLPreviewRequestIsCancelled(preview)) {
26 | return noErr;
27 | }
28 |
29 | CFDictionaryRef properties = [adManager buildPreviewProperties];
30 |
31 | if (QLPreviewRequestIsCancelled(preview)) {
32 | return noErr;
33 | }
34 |
35 | QLPreviewRequestSetDataRepresentation(preview, data, kUTTypeHTML, properties);
36 | return noErr;
37 | }
38 |
39 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview)
40 | {
41 | // Implement only if supported
42 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # .gitignore
2 | #
3 | # Files to ignore for Xcode projects
4 | #
5 | # Based on Swift gitignore template in the github/gitignore repository at:
6 | # https://github.com/github/gitignore/blob/5f15ed83c7a3d5db29845edae5205ca2d795c3d8/Swift.gitignore
7 |
8 | ## Build generated
9 | build/
10 | DerivedData/
11 |
12 | ## Various settings
13 | *.pbxuser
14 | !default.pbxuser
15 | *.mode1v3
16 | !default.mode1v3
17 | *.mode2v3
18 | !default.mode2v3
19 | *.perspectivev3
20 | !default.perspectivev3
21 | xcuserdata/
22 |
23 | ## Other
24 | *.moved-aside
25 | *.xccheckout
26 | *.xcscmblueprint
27 |
28 | ## Obj-C/Swift specific
29 | *.hmap
30 | *.ipa
31 | *.dSYM.zip
32 | *.dSYM
33 |
34 | ## Playgrounds
35 | timeline.xctimeline
36 | playground.xcworkspace
37 |
38 | # Swift Package Manager
39 | #
40 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
41 | # Packages/
42 | # Package.pins
43 | # Package.resolved
44 | .build/
45 |
46 | # CocoaPods
47 | #
48 | # We recommend against adding the Pods directory to your .gitignore. However
49 | # you should judge for yourself, the pros and cons are mentioned at:
50 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
51 | #
52 | # Pods/
53 |
54 | # Carthage
55 | #
56 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
57 | # Carthage/Checkouts
58 |
59 | Carthage/Build
60 |
61 | # fastlane
62 | #
63 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
64 | # screenshots whenever they are needed.
65 | # For more information about the recommended setup visit:
66 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
67 |
68 | fastlane/report.xml
69 | fastlane/Preview.html
70 | fastlane/screenshots
71 | fastlane/test_output
72 |
--------------------------------------------------------------------------------
/AsciiDocQuickLook/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDocumentTypes
8 |
9 |
10 | CFBundleTypeRole
11 | QLGenerator
12 | LSItemContentTypes
13 |
14 | org.asciidoc
15 |
16 |
17 |
18 | CFBundleExecutable
19 | $(EXECUTABLE_NAME)
20 | CFBundleIdentifier
21 | $(PRODUCT_BUNDLE_IDENTIFIER)
22 | CFBundleInfoDictionaryVersion
23 | 6.0
24 | CFBundleName
25 | $(PRODUCT_NAME)
26 | CFBundleShortVersionString
27 | 1.0.1
28 | CFBundleSignature
29 | ????
30 | CFBundleVersion
31 | 1
32 | CFPlugInDynamicRegisterFunction
33 |
34 | CFPlugInDynamicRegistration
35 | NO
36 | CFPlugInFactories
37 |
38 | D12D2AD4-0B90-47BD-8E2A-CEF2E6D083BF
39 | QuickLookGeneratorPluginFactory
40 |
41 | CFPlugInTypes
42 |
43 | 5E2D9680-5022-40FA-B806-43349622E5B9
44 |
45 | D12D2AD4-0B90-47BD-8E2A-CEF2E6D083BF
46 |
47 |
48 | CFPlugInUnloadFunction
49 |
50 | LSApplicationCategoryType
51 |
52 | NSHumanReadableCopyright
53 | Copyright © 2016 Clyde Clements. All rights reserved.
54 | QLNeedsToBeRunInMainThread
55 |
56 | QLPreviewHeight
57 | 600
58 | QLPreviewWidth
59 | 800
60 | QLSupportsConcurrentRequests
61 |
62 | QLThumbnailMinimumSize
63 | 17
64 | UTImportedTypeDeclarations
65 |
66 |
67 | UTTypeConformsTo
68 |
69 | public.plain-text
70 |
71 | UTTypeDescription
72 | AsciiDoc document
73 | UTTypeIconFile
74 | public.text.icns
75 | UTTypeIdentifier
76 | org.asciidoc
77 | UTTypeTagSpecification
78 |
79 | public.filename-extension
80 |
81 | ad
82 | adoc
83 | asciidoc
84 |
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/AsciiDocQuickLook/AsciiDocManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AsciiDocManager.swift
3 | // AsciiDocQuickLook
4 | //
5 | // Created by Clyde Clements on 2016-06-22.
6 | // Copyright © 2016 Clyde Clements. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import QuickLook
11 |
12 | @objc open class AsciiDocManager: NSObject {
13 | fileprivate let url: URL
14 |
15 | public init(withUrl url: URL) {
16 | self.url = url
17 | }
18 |
19 | fileprivate func buildData(_ type: String) -> Data? {
20 | let task = Process()
21 | var useDefaultConverter = true
22 | if let prefs = UserDefaults.init(suiteName: "ca.bluemist2.AsciiDocQuickLook") {
23 | if let converter = prefs.string(forKey: "AsciiDocConverter") {
24 | let msg = "AsciiDoc Quick Look: using user-specified " +
25 | "converter \(converter)"
26 | NSLog(msg)
27 | task.launchPath = converter
28 | useDefaultConverter = false
29 | }
30 | }
31 | if useDefaultConverter {
32 | // The PATH setting must include /usr/local/bin in order for the
33 | // asciidoctor script to run with /usr/local/bin/ruby (if installed)
34 | // instead of /usr/bin/ruby.
35 | task.environment = [
36 | "PATH": "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
37 | ]
38 | task.launchPath = "/usr/local/bin/asciidoctor"
39 | task.arguments = [
40 | "-b", "html5", "-a", "nofooter", "-o", "-", url.path
41 | ]
42 | } else {
43 | task.arguments = [url.path]
44 | }
45 | let pipe = Pipe()
46 | task.standardOutput = pipe
47 | var output = Data()
48 | let pipeOutputHandle = pipe.fileHandleForReading
49 | pipeOutputHandle.readabilityHandler = { pipe in
50 | output.append(pipe.availableData)
51 | }
52 | task.terminationHandler = { task in
53 | pipeOutputHandle.readabilityHandler = nil
54 | }
55 | task.launch()
56 | task.waitUntilExit()
57 |
58 | if (task.terminationStatus != 0) {
59 | let msg = "AsciiDoc Quick Look: " +
60 | "converter termination status \(task.terminationStatus); " +
61 | "unable to create data for \(type)"
62 | NSLog(msg)
63 | return nil
64 | }
65 |
66 | return output
67 | }
68 |
69 | open func buildPreview() -> Data? {
70 | return buildData("preview")
71 | }
72 |
73 | open func buildThumbnail() -> Data? {
74 | return buildData("thumbnail")
75 | }
76 |
77 | open func buildPreviewProperties() -> CFDictionary {
78 | return [
79 | kQLPreviewPropertyTextEncodingNameKey as String : "UTF-8",
80 | kQLPreviewPropertyMIMETypeKey as String : "text/html"
81 | ] as CFDictionary
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/AsciiDocQuickLook/GenerateThumbnailForURL.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 | #import
5 | #import
6 | #import "AsciiDocQuickLook-Swift.h"
7 |
8 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize);
9 | void CancelThumbnailGeneration(void *thisInterface, QLThumbnailRequestRef thumbnail);
10 |
11 | /* -----------------------------------------------------------------------------
12 | Generate a thumbnail for file
13 |
14 | This function's job is to create thumbnail for designated file as fast as possible
15 | ----------------------------------------------------------------------------- */
16 |
17 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize)
18 | {
19 | if (QLThumbnailRequestIsCancelled(thumbnail)) {
20 | return noErr;
21 | }
22 |
23 | AsciiDocManager* adManager = [[AsciiDocManager alloc] initWithUrl:(__bridge NSURL *)url];
24 | CFDataRef data = (__bridge CFDataRef)[adManager buildThumbnail];
25 |
26 | if (QLThumbnailRequestIsCancelled(thumbnail)) {
27 | return noErr;
28 | }
29 |
30 | NSRect viewRect = NSMakeRect(0.0, 0.0, 600.0, 800.0);
31 | float scale = maxSize.height / 800.0;
32 | NSSize scaleSize = NSMakeSize(scale, scale);
33 | CGSize thumbSize = NSSizeToCGSize(NSMakeSize((maxSize.width * (600.0/800.0)), maxSize.height));
34 |
35 | WebView* webView = [[WebView alloc] initWithFrame: viewRect];
36 | [webView scaleUnitSquareToSize: scaleSize];
37 | [webView.mainFrame.frameView setAllowsScrolling:NO];
38 | [webView.mainFrame loadData: (__bridge NSData *)(data)
39 | MIMEType: @"text/html"
40 | textEncodingName: @"utf-8"
41 | baseURL: (__bridge NSURL *)(url)];
42 |
43 | while([webView isLoading]) {
44 | if (QLThumbnailRequestIsCancelled(thumbnail)) {
45 | return noErr;
46 | }
47 | CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true);
48 | }
49 |
50 | [webView display];
51 |
52 | CGContextRef context = QLThumbnailRequestCreateContext(thumbnail, thumbSize, false, NULL);
53 |
54 | if (context) {
55 | NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:(void *)context flipped:[webView isFlipped]];
56 | [webView displayRectIgnoringOpacity:webView.bounds inContext:nsContext];
57 |
58 | QLThumbnailRequestFlushContext(thumbnail, context);
59 |
60 | CFRelease(context);
61 | }
62 |
63 | return noErr;
64 | }
65 |
66 | void CancelThumbnailGeneration(void *thisInterface, QLThumbnailRequestRef thumbnail)
67 | {
68 | // Implement only if supported
69 | }
70 |
--------------------------------------------------------------------------------
/README.adoc:
--------------------------------------------------------------------------------
1 | = AsciiDoc Quick Look
2 |
3 | :url-releases: https://github.com/clydeclements/AsciiDocQuickLook/releases
4 | :url-what-is-asciidoc: http://asciidoctor.org/docs/what-is-asciidoc/
5 | :url-asciidoctor: http://asciidoctor.org/
6 | :url-terminating-processes: https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/Lifecycle.html#//apple_ref/doc/uid/10000172i-SW3-114794-BAJIBGGI
7 | :url-asciidoctorjs: http://asciidoctor.org/docs/install-and-use-asciidoctorjs
8 | :url-qlswift: https://github.com/lexrus/QLSwift
9 |
10 |
11 | == Introduction
12 |
13 | This is a Quick Look plug-in for {url-what-is-asciidoc}[AsciiDoc] format files.
14 | It renders a preview of an AsciiDoc file selected in the Finder by using
15 | {url-asciidoctor}[Asciidoctor].
16 |
17 | == Installation
18 |
19 | * By default this plug-in uses Asciidoctor to render the preview. Therefore,
20 | first install that program via your preferred method. For example, to install
21 | via the system `gem` command, use:
22 |
23 | sudo gem install asciidoctor
24 |
25 | * Download a zipped {url-releases}[binary] of this plug-in. Unzip and move
26 | `AsciiDoc.qlgenerator` into `/Library/QuickLook`. Note the plug-in will not
27 | work if installed to a user directory `~/Library/QuickLook` due to restraints
28 | imposed by the sand-boxing of Quick Look plug-ins.
29 |
30 | * Lastly, open Terminal and run the command `qlmanage -r` to reset the Quick
31 | Look Server.
32 |
33 | == Customization
34 |
35 | The preview of an AsciiDoc file is generated by converting it to HTML via
36 | Asciidoctor and displaying the resultant HTML. This process can be customized
37 | by setting a preference to override the converter:
38 |
39 | defaults write ca.bluemist2.AsciiDocQuickLook AsciiDocConverter /path/to/my_converter
40 |
41 | The last part of the above command must give the full path to an executable
42 | that accepts one argument, the name of the AsciiDoc file to be previewed, and
43 | writes the corresponding HTML format on standard output. For example, create
44 | a shell script called `asciidoc_to_html` with content similar to the following:
45 |
46 | #!/bin/bash
47 | export PATH=/usr/local/bin:$PATH
48 | asciidoctor -b html5 -a nofooter -a icons=font -o - "$1"
49 |
50 | Ensure the script is executable (use `chmod +x asciidoc_to_html`) and place it
51 | in your `~/bin` folder (create the folder if it does not exist). Lastly, set
52 | the converter preference:
53 |
54 | defaults write ca.bluemist2.AsciiDocQuickLook AsciiDocConverter ~/bin/asciidoc_to_html
55 |
56 | == To Do
57 |
58 | * A process should support sudden termination for the best user experience;
59 | see {url-terminating-processes}[Terminating Processes]. This plug-in works by
60 | launching an Asciidoctor process. Could the handling of this process be
61 | improved?
62 |
63 | * Consider using {url-asciidoctorjs}[asciidoctor.js] to generate previews.
64 | Examine {url-qlswift}[QLSwift] to see how it generates previews using
65 | JavaScript. This method would not require the Asciidoctor program to be
66 | installed (though it would require distribution of `asciidoctor.js`) and it
67 | would not need to launch a separate process.
68 |
69 | == Release History
70 |
71 | * 1.0 (2017-11-06): Initial release
72 |
73 | == License
74 |
75 | Copyright (C) 2017 Clyde Clements
76 |
77 | The AsciiDoc Quick Look plug-in is distributed under the MIT license. See the
78 | link:LICENSE.txt[license] file for more information.
79 |
--------------------------------------------------------------------------------
/AsciiDocQuickLook/main.c:
--------------------------------------------------------------------------------
1 | //==============================================================================
2 | //
3 | // DO NO MODIFY THE CONTENT OF THIS FILE
4 | //
5 | // This file contains the generic CFPlug-in code necessary for your generator
6 | // To complete your generator implement the function in GenerateThumbnailForURL/GeneratePreviewForURL.c
7 | //
8 | //==============================================================================
9 |
10 |
11 |
12 |
13 |
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | // -----------------------------------------------------------------------------
21 | // constants
22 | // -----------------------------------------------------------------------------
23 |
24 | // Don't modify this line
25 | #define PLUGIN_ID "D12D2AD4-0B90-47BD-8E2A-CEF2E6D083BF"
26 |
27 | //
28 | // Below is the generic glue code for all plug-ins.
29 | //
30 | // You should not have to modify this code aside from changing
31 | // names if you decide to change the names defined in the Info.plist
32 | //
33 |
34 |
35 | // -----------------------------------------------------------------------------
36 | // typedefs
37 | // -----------------------------------------------------------------------------
38 |
39 | // The thumbnail generation function to be implemented in GenerateThumbnailForURL.c
40 | OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize);
41 | void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail);
42 |
43 | // The preview generation function to be implemented in GeneratePreviewForURL.c
44 | OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
45 | void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview);
46 |
47 | // The layout for an instance of QuickLookGeneratorPlugIn
48 | typedef struct __QuickLookGeneratorPluginType
49 | {
50 | void *conduitInterface;
51 | CFUUIDRef factoryID;
52 | UInt32 refCount;
53 | } QuickLookGeneratorPluginType;
54 |
55 | // -----------------------------------------------------------------------------
56 | // prototypes
57 | // -----------------------------------------------------------------------------
58 | // Forward declaration for the IUnknown implementation.
59 | //
60 |
61 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID);
62 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance);
63 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
64 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
65 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance);
66 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance);
67 |
68 | // -----------------------------------------------------------------------------
69 | // myInterfaceFtbl definition
70 | // -----------------------------------------------------------------------------
71 | // The QLGeneratorInterfaceStruct function table.
72 | //
73 | static QLGeneratorInterfaceStruct myInterfaceFtbl = {
74 | NULL,
75 | QuickLookGeneratorQueryInterface,
76 | QuickLookGeneratorPluginAddRef,
77 | QuickLookGeneratorPluginRelease,
78 | NULL,
79 | NULL,
80 | NULL,
81 | NULL
82 | };
83 |
84 |
85 | // -----------------------------------------------------------------------------
86 | // AllocQuickLookGeneratorPluginType
87 | // -----------------------------------------------------------------------------
88 | // Utility function that allocates a new instance.
89 | // You can do some initial setup for the generator here if you wish
90 | // like allocating globals etc...
91 | //
92 | QuickLookGeneratorPluginType *AllocQuickLookGeneratorPluginType(CFUUIDRef inFactoryID)
93 | {
94 | QuickLookGeneratorPluginType *theNewInstance;
95 |
96 | theNewInstance = (QuickLookGeneratorPluginType *)malloc(sizeof(QuickLookGeneratorPluginType));
97 | memset(theNewInstance,0,sizeof(QuickLookGeneratorPluginType));
98 |
99 | /* Point to the function table Malloc enough to store the stuff and copy the filler from myInterfaceFtbl over */
100 | theNewInstance->conduitInterface = malloc(sizeof(QLGeneratorInterfaceStruct));
101 | memcpy(theNewInstance->conduitInterface,&myInterfaceFtbl,sizeof(QLGeneratorInterfaceStruct));
102 |
103 | /* Retain and keep an open instance refcount for each factory. */
104 | theNewInstance->factoryID = CFRetain(inFactoryID);
105 | CFPlugInAddInstanceForFactory(inFactoryID);
106 |
107 | /* This function returns the IUnknown interface so set the refCount to one. */
108 | theNewInstance->refCount = 1;
109 | return theNewInstance;
110 | }
111 |
112 | // -----------------------------------------------------------------------------
113 | // DeallocQuickLookGeneratorPluginType
114 | // -----------------------------------------------------------------------------
115 | // Utility function that deallocates the instance when
116 | // the refCount goes to zero.
117 | // In the current implementation generator interfaces are never deallocated
118 | // but implement this as this might change in the future
119 | //
120 | void DeallocQuickLookGeneratorPluginType(QuickLookGeneratorPluginType *thisInstance)
121 | {
122 | CFUUIDRef theFactoryID;
123 |
124 | theFactoryID = thisInstance->factoryID;
125 | /* Free the conduitInterface table up */
126 | free(thisInstance->conduitInterface);
127 |
128 | /* Free the instance structure */
129 | free(thisInstance);
130 | if (theFactoryID){
131 | CFPlugInRemoveInstanceForFactory(theFactoryID);
132 | CFRelease(theFactoryID);
133 | }
134 | }
135 |
136 | // -----------------------------------------------------------------------------
137 | // QuickLookGeneratorQueryInterface
138 | // -----------------------------------------------------------------------------
139 | // Implementation of the IUnknown QueryInterface function.
140 | //
141 | HRESULT QuickLookGeneratorQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv)
142 | {
143 | CFUUIDRef interfaceID;
144 |
145 | interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
146 |
147 | if (CFEqual(interfaceID,kQLGeneratorCallbacksInterfaceID)){
148 | /* If the Right interface was requested, bump the ref count,
149 | * set the ppv parameter equal to the instance, and
150 | * return good status.
151 | */
152 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GenerateThumbnailForURL = GenerateThumbnailForURL;
153 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelThumbnailGeneration = CancelThumbnailGeneration;
154 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->GeneratePreviewForURL = GeneratePreviewForURL;
155 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType *)thisInstance)->conduitInterface)->CancelPreviewGeneration = CancelPreviewGeneration;
156 | ((QLGeneratorInterfaceStruct *)((QuickLookGeneratorPluginType*)thisInstance)->conduitInterface)->AddRef(thisInstance);
157 | *ppv = thisInstance;
158 | CFRelease(interfaceID);
159 | return S_OK;
160 | }else{
161 | /* Requested interface unknown, bail with error. */
162 | *ppv = NULL;
163 | CFRelease(interfaceID);
164 | return E_NOINTERFACE;
165 | }
166 | }
167 |
168 | // -----------------------------------------------------------------------------
169 | // QuickLookGeneratorPluginAddRef
170 | // -----------------------------------------------------------------------------
171 | // Implementation of reference counting for this type. Whenever an interface
172 | // is requested, bump the refCount for the instance. NOTE: returning the
173 | // refcount is a convention but is not required so don't rely on it.
174 | //
175 | ULONG QuickLookGeneratorPluginAddRef(void *thisInstance)
176 | {
177 | ((QuickLookGeneratorPluginType *)thisInstance )->refCount += 1;
178 | return ((QuickLookGeneratorPluginType*) thisInstance)->refCount;
179 | }
180 |
181 | // -----------------------------------------------------------------------------
182 | // QuickLookGeneratorPluginRelease
183 | // -----------------------------------------------------------------------------
184 | // When an interface is released, decrement the refCount.
185 | // If the refCount goes to zero, deallocate the instance.
186 | //
187 | ULONG QuickLookGeneratorPluginRelease(void *thisInstance)
188 | {
189 | ((QuickLookGeneratorPluginType*)thisInstance)->refCount -= 1;
190 | if (((QuickLookGeneratorPluginType*)thisInstance)->refCount == 0){
191 | DeallocQuickLookGeneratorPluginType((QuickLookGeneratorPluginType*)thisInstance );
192 | return 0;
193 | }else{
194 | return ((QuickLookGeneratorPluginType*) thisInstance )->refCount;
195 | }
196 | }
197 |
198 | // -----------------------------------------------------------------------------
199 | // QuickLookGeneratorPluginFactory
200 | // -----------------------------------------------------------------------------
201 | void *QuickLookGeneratorPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
202 | {
203 | QuickLookGeneratorPluginType *result;
204 | CFUUIDRef uuid;
205 |
206 | /* If correct type is being requested, allocate an
207 | * instance of kQLGeneratorTypeID and return the IUnknown interface.
208 | */
209 | if (CFEqual(typeID,kQLGeneratorTypeID)){
210 | uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
211 | result = AllocQuickLookGeneratorPluginType(uuid);
212 | CFRelease(uuid);
213 | return result;
214 | }
215 | /* If the requested type is incorrect, return NULL. */
216 | return NULL;
217 | }
218 |
219 |
--------------------------------------------------------------------------------
/AsciiDocQuickLook.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | C27DE3711FAF69F80057F054 /* README.adoc in Resources */ = {isa = PBXBuildFile; fileRef = C27DE3701FAF69F80057F054 /* README.adoc */; };
11 | C2D158ED1D1B1AF2009BC66B /* GenerateThumbnailForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = C2D158EC1D1B1AF2009BC66B /* GenerateThumbnailForURL.m */; };
12 | C2D158EF1D1B1AF2009BC66B /* GeneratePreviewForURL.m in Sources */ = {isa = PBXBuildFile; fileRef = C2D158EE1D1B1AF2009BC66B /* GeneratePreviewForURL.m */; };
13 | C2D158F11D1B1AF2009BC66B /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = C2D158F01D1B1AF2009BC66B /* main.c */; };
14 | C2D158FA1D1B1CFC009BC66B /* AsciiDocManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2D158F91D1B1CFC009BC66B /* AsciiDocManager.swift */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXFileReference section */
18 | C27DE3701FAF69F80057F054 /* README.adoc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.adoc; sourceTree = ""; };
19 | C2D158E91D1B1AF2009BC66B /* AsciiDoc.qlgenerator */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AsciiDoc.qlgenerator; sourceTree = BUILT_PRODUCTS_DIR; };
20 | C2D158EC1D1B1AF2009BC66B /* GenerateThumbnailForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GenerateThumbnailForURL.m; sourceTree = ""; };
21 | C2D158EE1D1B1AF2009BC66B /* GeneratePreviewForURL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GeneratePreviewForURL.m; sourceTree = ""; };
22 | C2D158F01D1B1AF2009BC66B /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; };
23 | C2D158F21D1B1AF2009BC66B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
24 | C2D158F81D1B1CFC009BC66B /* AsciiDocQuickLook-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AsciiDocQuickLook-Bridging-Header.h"; sourceTree = ""; };
25 | C2D158F91D1B1CFC009BC66B /* AsciiDocManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsciiDocManager.swift; sourceTree = ""; };
26 | /* End PBXFileReference section */
27 |
28 | /* Begin PBXFrameworksBuildPhase section */
29 | C2D158E51D1B1AF2009BC66B /* Frameworks */ = {
30 | isa = PBXFrameworksBuildPhase;
31 | buildActionMask = 2147483647;
32 | files = (
33 | );
34 | runOnlyForDeploymentPostprocessing = 0;
35 | };
36 | /* End PBXFrameworksBuildPhase section */
37 |
38 | /* Begin PBXGroup section */
39 | C2D158DF1D1B1AF2009BC66B = {
40 | isa = PBXGroup;
41 | children = (
42 | C27DE3701FAF69F80057F054 /* README.adoc */,
43 | C2D158EB1D1B1AF2009BC66B /* AsciiDocQuickLook */,
44 | C2D158EA1D1B1AF2009BC66B /* Products */,
45 | );
46 | sourceTree = "";
47 | };
48 | C2D158EA1D1B1AF2009BC66B /* Products */ = {
49 | isa = PBXGroup;
50 | children = (
51 | C2D158E91D1B1AF2009BC66B /* AsciiDoc.qlgenerator */,
52 | );
53 | name = Products;
54 | sourceTree = "";
55 | };
56 | C2D158EB1D1B1AF2009BC66B /* AsciiDocQuickLook */ = {
57 | isa = PBXGroup;
58 | children = (
59 | C2D158EC1D1B1AF2009BC66B /* GenerateThumbnailForURL.m */,
60 | C2D158EE1D1B1AF2009BC66B /* GeneratePreviewForURL.m */,
61 | C2D158F91D1B1CFC009BC66B /* AsciiDocManager.swift */,
62 | C2D158F01D1B1AF2009BC66B /* main.c */,
63 | C2D158F21D1B1AF2009BC66B /* Info.plist */,
64 | C2D158F81D1B1CFC009BC66B /* AsciiDocQuickLook-Bridging-Header.h */,
65 | );
66 | path = AsciiDocQuickLook;
67 | sourceTree = "";
68 | };
69 | /* End PBXGroup section */
70 |
71 | /* Begin PBXHeadersBuildPhase section */
72 | C2D158E61D1B1AF2009BC66B /* Headers */ = {
73 | isa = PBXHeadersBuildPhase;
74 | buildActionMask = 2147483647;
75 | files = (
76 | );
77 | runOnlyForDeploymentPostprocessing = 0;
78 | };
79 | /* End PBXHeadersBuildPhase section */
80 |
81 | /* Begin PBXNativeTarget section */
82 | C2D158E81D1B1AF2009BC66B /* AsciiDoc */ = {
83 | isa = PBXNativeTarget;
84 | buildConfigurationList = C2D158F51D1B1AF2009BC66B /* Build configuration list for PBXNativeTarget "AsciiDoc" */;
85 | buildPhases = (
86 | C2D158E41D1B1AF2009BC66B /* Sources */,
87 | C2D158E51D1B1AF2009BC66B /* Frameworks */,
88 | C2D158E61D1B1AF2009BC66B /* Headers */,
89 | C2D158E71D1B1AF2009BC66B /* Resources */,
90 | );
91 | buildRules = (
92 | );
93 | dependencies = (
94 | );
95 | name = AsciiDoc;
96 | productName = AsciiDoc;
97 | productReference = C2D158E91D1B1AF2009BC66B /* AsciiDoc.qlgenerator */;
98 | productType = "com.apple.product-type.bundle";
99 | };
100 | /* End PBXNativeTarget section */
101 |
102 | /* Begin PBXProject section */
103 | C2D158E01D1B1AF2009BC66B /* Project object */ = {
104 | isa = PBXProject;
105 | attributes = {
106 | LastUpgradeCheck = 0820;
107 | ORGANIZATIONNAME = "Clyde Clements";
108 | TargetAttributes = {
109 | C2D158E81D1B1AF2009BC66B = {
110 | CreatedOnToolsVersion = 7.3.1;
111 | DevelopmentTeam = LYJQR9E3B7;
112 | LastSwiftMigration = 0820;
113 | ProvisioningStyle = Automatic;
114 | };
115 | };
116 | };
117 | buildConfigurationList = C2D158E31D1B1AF2009BC66B /* Build configuration list for PBXProject "AsciiDocQuickLook" */;
118 | compatibilityVersion = "Xcode 3.2";
119 | developmentRegion = English;
120 | hasScannedForEncodings = 0;
121 | knownRegions = (
122 | en,
123 | );
124 | mainGroup = C2D158DF1D1B1AF2009BC66B;
125 | productRefGroup = C2D158EA1D1B1AF2009BC66B /* Products */;
126 | projectDirPath = "";
127 | projectRoot = "";
128 | targets = (
129 | C2D158E81D1B1AF2009BC66B /* AsciiDoc */,
130 | );
131 | };
132 | /* End PBXProject section */
133 |
134 | /* Begin PBXResourcesBuildPhase section */
135 | C2D158E71D1B1AF2009BC66B /* Resources */ = {
136 | isa = PBXResourcesBuildPhase;
137 | buildActionMask = 2147483647;
138 | files = (
139 | C27DE3711FAF69F80057F054 /* README.adoc in Resources */,
140 | );
141 | runOnlyForDeploymentPostprocessing = 0;
142 | };
143 | /* End PBXResourcesBuildPhase section */
144 |
145 | /* Begin PBXSourcesBuildPhase section */
146 | C2D158E41D1B1AF2009BC66B /* Sources */ = {
147 | isa = PBXSourcesBuildPhase;
148 | buildActionMask = 2147483647;
149 | files = (
150 | C2D158ED1D1B1AF2009BC66B /* GenerateThumbnailForURL.m in Sources */,
151 | C2D158EF1D1B1AF2009BC66B /* GeneratePreviewForURL.m in Sources */,
152 | C2D158FA1D1B1CFC009BC66B /* AsciiDocManager.swift in Sources */,
153 | C2D158F11D1B1AF2009BC66B /* main.c in Sources */,
154 | );
155 | runOnlyForDeploymentPostprocessing = 0;
156 | };
157 | /* End PBXSourcesBuildPhase section */
158 |
159 | /* Begin XCBuildConfiguration section */
160 | C2D158F31D1B1AF2009BC66B /* Debug */ = {
161 | isa = XCBuildConfiguration;
162 | buildSettings = {
163 | ALWAYS_SEARCH_USER_PATHS = NO;
164 | CLANG_ANALYZER_NONNULL = YES;
165 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
166 | CLANG_CXX_LIBRARY = "libc++";
167 | CLANG_ENABLE_MODULES = YES;
168 | CLANG_ENABLE_OBJC_ARC = YES;
169 | CLANG_WARN_BOOL_CONVERSION = YES;
170 | CLANG_WARN_CONSTANT_CONVERSION = YES;
171 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
172 | CLANG_WARN_EMPTY_BODY = YES;
173 | CLANG_WARN_ENUM_CONVERSION = YES;
174 | CLANG_WARN_INFINITE_RECURSION = YES;
175 | CLANG_WARN_INT_CONVERSION = YES;
176 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
177 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
178 | CLANG_WARN_UNREACHABLE_CODE = YES;
179 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
180 | CODE_SIGN_IDENTITY = "-";
181 | COPY_PHASE_STRIP = NO;
182 | DEBUG_INFORMATION_FORMAT = dwarf;
183 | ENABLE_STRICT_OBJC_MSGSEND = YES;
184 | ENABLE_TESTABILITY = YES;
185 | GCC_C_LANGUAGE_STANDARD = gnu99;
186 | GCC_DYNAMIC_NO_PIC = NO;
187 | GCC_NO_COMMON_BLOCKS = YES;
188 | GCC_OPTIMIZATION_LEVEL = 0;
189 | GCC_PREPROCESSOR_DEFINITIONS = (
190 | "DEBUG=1",
191 | "$(inherited)",
192 | );
193 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
194 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
195 | GCC_WARN_UNDECLARED_SELECTOR = YES;
196 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
197 | GCC_WARN_UNUSED_FUNCTION = YES;
198 | GCC_WARN_UNUSED_VARIABLE = YES;
199 | MACOSX_DEPLOYMENT_TARGET = 10.11;
200 | MTL_ENABLE_DEBUG_INFO = YES;
201 | ONLY_ACTIVE_ARCH = YES;
202 | SDKROOT = macosx;
203 | };
204 | name = Debug;
205 | };
206 | C2D158F41D1B1AF2009BC66B /* Release */ = {
207 | isa = XCBuildConfiguration;
208 | buildSettings = {
209 | ALWAYS_SEARCH_USER_PATHS = NO;
210 | CLANG_ANALYZER_NONNULL = YES;
211 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
212 | CLANG_CXX_LIBRARY = "libc++";
213 | CLANG_ENABLE_MODULES = YES;
214 | CLANG_ENABLE_OBJC_ARC = YES;
215 | CLANG_WARN_BOOL_CONVERSION = YES;
216 | CLANG_WARN_CONSTANT_CONVERSION = YES;
217 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
218 | CLANG_WARN_EMPTY_BODY = YES;
219 | CLANG_WARN_ENUM_CONVERSION = YES;
220 | CLANG_WARN_INFINITE_RECURSION = YES;
221 | CLANG_WARN_INT_CONVERSION = YES;
222 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
223 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
224 | CLANG_WARN_UNREACHABLE_CODE = YES;
225 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
226 | CODE_SIGN_IDENTITY = "-";
227 | COPY_PHASE_STRIP = NO;
228 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
229 | ENABLE_NS_ASSERTIONS = NO;
230 | ENABLE_STRICT_OBJC_MSGSEND = YES;
231 | GCC_C_LANGUAGE_STANDARD = gnu99;
232 | GCC_NO_COMMON_BLOCKS = YES;
233 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
234 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
235 | GCC_WARN_UNDECLARED_SELECTOR = YES;
236 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
237 | GCC_WARN_UNUSED_FUNCTION = YES;
238 | GCC_WARN_UNUSED_VARIABLE = YES;
239 | MACOSX_DEPLOYMENT_TARGET = 10.11;
240 | MTL_ENABLE_DEBUG_INFO = NO;
241 | SDKROOT = macosx;
242 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
243 | };
244 | name = Release;
245 | };
246 | C2D158F61D1B1AF2009BC66B /* Debug */ = {
247 | isa = XCBuildConfiguration;
248 | buildSettings = {
249 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
250 | CLANG_ENABLE_MODULES = YES;
251 | CODE_SIGN_IDENTITY = "Mac Developer";
252 | COMBINE_HIDPI_IMAGES = YES;
253 | INFOPLIST_FILE = AsciiDocQuickLook/Info.plist;
254 | INSTALL_PATH = /Library/QuickLook;
255 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks";
256 | PRODUCT_BUNDLE_IDENTIFIER = ca.bluemist2.AsciiDocQuickLook;
257 | PRODUCT_NAME = AsciiDoc;
258 | SWIFT_OBJC_BRIDGING_HEADER = "AsciiDocQuickLook/AsciiDocQuickLook-Bridging-Header.h";
259 | SWIFT_OBJC_INTERFACE_HEADER_NAME = "$(SWIFT_MODULE_NAME)QuickLook-Swift.h";
260 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
261 | SWIFT_VERSION = 3.0;
262 | WRAPPER_EXTENSION = qlgenerator;
263 | };
264 | name = Debug;
265 | };
266 | C2D158F71D1B1AF2009BC66B /* Release */ = {
267 | isa = XCBuildConfiguration;
268 | buildSettings = {
269 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
270 | CLANG_ENABLE_MODULES = YES;
271 | CODE_SIGN_IDENTITY = "Mac Developer";
272 | COMBINE_HIDPI_IMAGES = YES;
273 | INFOPLIST_FILE = AsciiDocQuickLook/Info.plist;
274 | INSTALL_PATH = /Library/QuickLook;
275 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks";
276 | PRODUCT_BUNDLE_IDENTIFIER = ca.bluemist2.AsciiDocQuickLook;
277 | PRODUCT_NAME = AsciiDoc;
278 | SWIFT_OBJC_BRIDGING_HEADER = "AsciiDocQuickLook/AsciiDocQuickLook-Bridging-Header.h";
279 | SWIFT_OBJC_INTERFACE_HEADER_NAME = "$(SWIFT_MODULE_NAME)QuickLook-Swift.h";
280 | SWIFT_VERSION = 3.0;
281 | WRAPPER_EXTENSION = qlgenerator;
282 | };
283 | name = Release;
284 | };
285 | /* End XCBuildConfiguration section */
286 |
287 | /* Begin XCConfigurationList section */
288 | C2D158E31D1B1AF2009BC66B /* Build configuration list for PBXProject "AsciiDocQuickLook" */ = {
289 | isa = XCConfigurationList;
290 | buildConfigurations = (
291 | C2D158F31D1B1AF2009BC66B /* Debug */,
292 | C2D158F41D1B1AF2009BC66B /* Release */,
293 | );
294 | defaultConfigurationIsVisible = 0;
295 | defaultConfigurationName = Release;
296 | };
297 | C2D158F51D1B1AF2009BC66B /* Build configuration list for PBXNativeTarget "AsciiDoc" */ = {
298 | isa = XCConfigurationList;
299 | buildConfigurations = (
300 | C2D158F61D1B1AF2009BC66B /* Debug */,
301 | C2D158F71D1B1AF2009BC66B /* Release */,
302 | );
303 | defaultConfigurationIsVisible = 0;
304 | defaultConfigurationName = Release;
305 | };
306 | /* End XCConfigurationList section */
307 | };
308 | rootObject = C2D158E01D1B1AF2009BC66B /* Project object */;
309 | }
310 |
--------------------------------------------------------------------------------