Revision: 14175
http://sourceforge.net/p/skim-app/code/14175
Author: hofman
Date: 2024-04-04 16:12:03 +0000 (Thu, 04 Apr 2024)
Log Message:
-----------
Let sync parser classes load the file in all cases. Conform classes to common
protocol, and loead them in unified mwethod. Let synchronizer keep track of
resolver source file names fo all parsers. Move concrete parsers to separate
files.
Modified Paths:
--------------
trunk/SKPDFSynchronizer.h
trunk/SKPDFSynchronizer.m
trunk/Skim.xcodeproj/project.pbxproj
Added Paths:
-----------
trunk/SKPDFSyncParser.h
trunk/SKPDFSyncParser.m
trunk/SKSyncTeXParser.h
trunk/SKSyncTeXParser.m
Added: trunk/SKPDFSyncParser.h
===================================================================
--- trunk/SKPDFSyncParser.h (rev 0)
+++ trunk/SKPDFSyncParser.h 2024-04-04 16:12:03 UTC (rev 14175)
@@ -0,0 +1,54 @@
+//
+// SKPDFSyncParser.h
+// Skim
+//
+// Created by Christiaan Hofman on 04/04/2024.
+/*
+ This software is Copyright (c) 2024
+ 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 "SKPDFSynchronizer.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class SKPDFSyncRecord;
+
+@interface SKPDFSyncParser : NSObject <SKSyncParser> {
+ NSMutableArray<NSMutableArray<SKPDFSyncRecord *> *> *pages;
+ NSMapTable *lines;
+ NSString *syncFileName;
+}
+- (void)loadPdfsyncFile;
+@end
+
+NS_ASSUME_NONNULL_END
Added: trunk/SKPDFSyncParser.m
===================================================================
--- trunk/SKPDFSyncParser.m (rev 0)
+++ trunk/SKPDFSyncParser.m 2024-04-04 16:12:03 UTC (rev 14175)
@@ -0,0 +1,305 @@
+//
+// SKPDFSyncParser.m
+// Skim
+//
+// Created by Christiaan Hofman on 04/04/2024.
+/*
+ This software is Copyright (c) 2024
+ 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 "SKPDFSyncParser.h"
+#import "SKPDFSyncRecord.h"
+#import "NSPointerFunctions_SKExtensions.h"
+#import "NSScanner_SKExtensions.h"
+
+// Offset of coordinates in PDFKit and what pdfsync tells us. Don't know what
they are; is this implementation dependent?
+static NSPoint pdfOffset = {0.0, 0.0};
+
+#define SKPDFSynchronizerPdfsyncExtension @"pdfsync"
+
+#define PDFSYNC_TO_PDF(coord) ((CGFloat)coord / 65536.0)
+
+@implementation SKPDFSyncParser
+
+@synthesize syncFileName;
+
+- (instancetype)initWithFileName:(NSString *)fileName {
+ self = [super init];
+ if (self) {
+ if ([[fileName pathExtension]
isEqualToString:SKPDFSynchronizerPdfsyncExtension])
+ syncFileName = fileName;
+ else
+ syncFileName = [[fileName stringByDeletingPathExtension]
stringByAppendingPathExtension:SKPDFSynchronizerPdfsyncExtension];
+ if ([[NSURL fileURLWithPath:syncFileName isDirectory:NO]
checkResourceIsReachableAndReturnError:NULL]) {
+ pages = [[NSMutableArray alloc] init];
+ lines = [[NSMapTable alloc]
initWithKeyPointerFunctions:[NSPointerFunctions
caseInsensitiveStringPointerFunctions]
valuePointerFunctions:[NSPointerFunctions strongPointerFunctions] capacity:0];
+ [self loadPdfsyncFile];
+ } else {
+ self = nil;
+ }
+ }
+ return self;
+}
+
+static inline NSString *removeQuotes(NSString *file) {
+ if ([file length] > 2 && [file characterAtIndex:0] == '"' && [file
characterAtIndex:[file length] - 1] == '"')
+ return [file substringWithRange:NSMakeRange(1, [file length] - 2)];
+ return file;
+}
+
+static inline SKPDFSyncRecord *recordForIndex(NSMapTable *records, NSInteger
recordIndex) {
+ SKPDFSyncRecord *record = (__bridge SKPDFSyncRecord *)NSMapGet(records,
(void *)recordIndex);
+ if (record == nil) {
+ record = [[SKPDFSyncRecord alloc] initWithRecordIndex:recordIndex];
+ NSMapInsert(records, (void *)recordIndex, (__bridge void *)record);
+ }
+ return record;
+}
+
+- (void)loadPdfsyncFile {
+
+ NSString *pdfsyncString = [NSString stringWithContentsOfFile:syncFileName
encoding:NSUTF8StringEncoding error:NULL];
+
+ if ([pdfsyncString length]) {
+
+ NSMapTable *records = [[NSMapTable alloc]
initWithKeyOptions:NSPointerFunctionsOpaqueMemory |
NSPointerFunctionsIntegerPersonality
valueOptions:NSPointerFunctionsStrongMemory |
NSPointerFunctionsObjectPersonality capacity:0];
+ NSMutableArray *files = [[NSMutableArray alloc] init];
+ NSString *file;
+ NSInteger recordIndex, line, pageIndex;
+ double x, y;
+ SKPDFSyncRecord *record;
+ unichar ch;
+ NSScanner *sc = [[NSScanner alloc] initWithString:pdfsyncString];
+ NSCharacterSet *newlines = [NSCharacterSet newlineCharacterSet];
+
+ [sc setCharactersToBeSkipped:[NSCharacterSet whitespaceCharacterSet]];
+
+ if ([sc scanUpToCharactersFromSet:newlines intoString:&file] &&
+ [sc scanCharactersFromSet:newlines intoString:NULL]) {
+
+ file = removeQuotes(file);
+ [files addObject:file];
+
+ [lines setObject:[NSMutableArray array] forKey:file];
+
+ // we ignore the version
+ if ([sc scanString:@"version" intoString:NULL] && [sc
scanInteger:NULL]) {
+
+ [sc scanCharactersFromSet:newlines intoString:NULL];
+
+ while ([sc scanCharacter:&ch]) {
+
+ switch (ch) {
+ case 'l':
+ if ([sc scanInteger:&recordIndex] && [sc
scanInteger:&line]) {
+ // we ignore the column
+ [sc scanInteger:NULL];
+ record = recordForIndex(records, recordIndex);
+ [record setFile:file];
+ [record setLine:line];
+ [[lines objectForKey:file] addObject:record];
+ }
+ break;
+ case 'p':
+ // we ignore * and + modifiers
+ if ([sc scanString:@"*" intoString:NULL] == NO)
+ [sc scanString:@"+" intoString:NULL];
+ if ([sc scanInteger:&recordIndex] && [sc
scanDouble:&x] && [sc scanDouble:&y]) {
+ record = recordForIndex(records, recordIndex);
+ [record setPageIndex:[pages count] - 1];
+ [record setPoint:NSMakePoint(PDFSYNC_TO_PDF(x)
+ pdfOffset.x, PDFSYNC_TO_PDF(y) + pdfOffset.y)];
+ [[pages lastObject] addObject:record];
+ }
+ break;
+ case 's':
+ // start of a new page, the scanned integer should
always equal [pages count]+1
+ if ([sc scanInteger:&pageIndex] == NO) pageIndex =
[pages count] + 1;
+ while (pageIndex > (NSInteger)[pages count])
+ [pages addObject:[NSMutableArray array]];
+ break;
+ case '(':
+ // start of a new source file
+ if ([sc scanUpToCharactersFromSet:newlines
intoString:&file]) {
+ file = removeQuotes(file);
+ [files addObject:file];
+ if ([lines objectForKey:file] == nil)
+ [lines setObject:[NSMutableArray array]
forKey:file];
+ }
+ break;
+ case ')':
+ // closing of a source file
+ if ([files count]) {
+ [files removeLastObject];
+ file = [files lastObject];
+ }
+ break;
+ default:
+ // shouldn't reach
+ break;
+ }
+
+ [sc scanUpToCharactersFromSet:newlines intoString:NULL];
+ [sc scanCharactersFromSet:newlines intoString:NULL];
+ }
+
+ NSArray *lineSortDescriptors = @[[[NSSortDescriptor alloc]
initWithKey:@"line" ascending:YES]];
+ NSArray *pointSortDescriptors = @[[[NSSortDescriptor alloc]
initWithKey:@"x" ascending:YES], [[NSSortDescriptor alloc] initWithKey:@"y"
ascending:NO]];
+
+ for (NSMutableArray *array in [lines objectEnumerator])
+ [array sortUsingDescriptors:lineSortDescriptors];
+ [pages
makeObjectsPerformSelector:@selector(sortUsingDescriptors:)
+ withObject:pointSortDescriptors];
+
+ }
+ }
+ }
+}
+
+- (void)enumerateSourceFilesUsingBlock:(void (^)(NSString *file))block {
+ for (NSString *file in lines)
+ block(file);
+}
+
+- (BOOL)findFileLine:(NSInteger *)linePtr file:(NSString * __autoreleasing
*)filePtr forLocation:(NSPoint)point inRect:(NSRect)rect
pageBounds:(NSRect)bounds atPageIndex:(NSUInteger)pageIndex {
+ BOOL rv = NO;
+ if (pageIndex < [pages count]) {
+
+ SKPDFSyncRecord *record = nil;
+ SKPDFSyncRecord *beforeRecord = nil;
+ SKPDFSyncRecord *afterRecord = nil;
+ NSMutableDictionary *atRecords = [NSMutableDictionary dictionary];
+
+ for (record in [pages objectAtIndex:pageIndex]) {
+ if ([record line] == 0)
+ continue;
+ NSPoint p = [record point];
+ if (p.y > NSMaxY(rect)) {
+ beforeRecord = record;
+ } else if (p.y < NSMinY(rect)) {
+ afterRecord = record;
+ break;
+ } else if (p.x < NSMinX(rect)) {
+ beforeRecord = record;
+ } else if (p.x > NSMaxX(rect)) {
+ afterRecord = record;
+ break;
+ } else {
+ [atRecords setObject:record forKey:[NSNumber
numberWithDouble:fabs(p.x - point.x)]];
+ }
+ }
+
+ record = nil;
+ if ([atRecords count]) {
+ NSNumber *nearest = [[[atRecords allKeys]
sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:0];
+ record = [atRecords objectForKey:nearest];
+ } else if (beforeRecord && afterRecord) {
+ NSPoint beforePoint = [beforeRecord point];
+ NSPoint afterPoint = [afterRecord point];
+ if (beforePoint.y - point.y < point.y - afterPoint.y)
+ record = beforeRecord;
+ else if (beforePoint.y - point.y > point.y - afterPoint.y)
+ record = afterRecord;
+ else if (beforePoint.x - point.x < point.x - afterPoint.x)
+ record = beforeRecord;
+ else if (beforePoint.x - point.x > point.x - afterPoint.x)
+ record = afterRecord;
+ else
+ record = beforeRecord;
+ } else if (beforeRecord) {
+ record = beforeRecord;
+ } else if (afterRecord) {
+ record = afterRecord;
+ }
+
+ if (record) {
+ *linePtr = [record line];
+ *filePtr = [record file];
+ rv = YES;
+ }
+ }
+ if (rv == NO)
+ NSLog(@"PDFSync was unable to find file and line.");
+ return rv;
+}
+
+- (BOOL)findPage:(NSUInteger *)pageIndexPtr location:(NSPoint *)pointPtr
forLine:(NSInteger)line inFile:(NSString *)file {
+ BOOL rv = NO;
+ NSArray *theLines = [lines objectForKey:file];
+ if (theLines) {
+
+ SKPDFSyncRecord *record = nil;
+ SKPDFSyncRecord *beforeRecord = nil;
+ SKPDFSyncRecord *afterRecord = nil;
+ SKPDFSyncRecord *atRecord = nil;
+
+ for (record in theLines) {
+ if ([record pageIndex] == NSNotFound)
+ continue;
+ NSInteger l = [record line];
+ if (l < line) {
+ beforeRecord = record;
+ } else if (l > line) {
+ afterRecord = record;
+ break;
+ } else {
+ atRecord = record;
+ break;
+ }
+ }
+
+ if (atRecord) {
+ record = atRecord;
+ } else if (beforeRecord && afterRecord) {
+ NSInteger beforeLine = [beforeRecord line];
+ NSInteger afterLine = [afterRecord line];
+ if (beforeLine - line > line - afterLine)
+ record = afterRecord;
+ else
+ record = beforeRecord;
+ } else if (beforeRecord) {
+ record = beforeRecord;
+ } else if (afterRecord) {
+ record = afterRecord;
+ }
+
+ if (record) {
+ *pageIndexPtr = [record pageIndex];
+ *pointPtr = [record point];
+ rv = YES;
+ }
+ }
+ if (rv == NO)
+ NSLog(@"PDFSync was unable to find location and page.");
+ return rv;
+}
+
+@end
Modified: trunk/SKPDFSynchronizer.h
===================================================================
--- trunk/SKPDFSynchronizer.h 2024-04-03 16:34:12 UTC (rev 14174)
+++ trunk/SKPDFSynchronizer.h 2024-04-04 16:12:03 UTC (rev 14175)
@@ -48,8 +48,7 @@
SKPDFSynchronizerFlippedMask = 1 << 2,
};
-@protocol SKPDFSynchronizerDelegate;
-@class SKSyncTeX, SKPDFSync;
+@protocol SKPDFSynchronizerDelegate, SKSyncParser;
@interface SKPDFSynchronizer : NSObject {
__weak id <SKPDFSynchronizerDelegate> delegate;
@@ -64,9 +63,11 @@
NSFileManager *fileManager;
- SKPDFSync *pdfsync;
- SKSyncTeX *synctex;
+ NSMutableDictionary *sourceFileNames;
+ id<SKSyncParser> parser;
+ BOOL isPdfsync;
+
_Atomic(BOOL) shouldKeepRunning;
}
@@ -74,7 +75,7 @@
@property (nullable, copy) NSString *fileName;
- (void)findFileAndLineForLocation:(NSPoint)point inRect:(NSRect)rect
pageBounds:(NSRect)bounds atPageIndex:(NSUInteger)pageIndex;
-- (void)findPageAndLocationForLine:(NSInteger)line inFile:(NSString *)file
options:(SKPDFSynchronizerOption)options;
+- (void)findPageAndLocationForLine:(NSInteger)line inFile:(nullable NSString
*)file options:(SKPDFSynchronizerOption)options;
// this must be called to stop the DO server from running in the server thread
- (void)terminate;
@@ -81,6 +82,7 @@
@end
+#pragma mark -
@protocol SKPDFSynchronizerDelegate <NSObject>
@@ -89,4 +91,19 @@
@end
+#pragma mark -
+
+@protocol SKSyncParser <NSObject>
+
+- (instancetype)initWithFileName:(NSString *)fileName;
+
+@property (nonatomic, nullable, readonly) NSString *syncFileName;
+
+- (void)enumerateSourceFilesUsingBlock:(void (^)(NSString *file))block;
+
+- (BOOL)findFileLine:(NSInteger *)linePtr file:(NSString * _Nullable
__autoreleasing * _Nonnull)filePtr forLocation:(NSPoint)point
inRect:(NSRect)rect pageBounds:(NSRect)bounds atPageIndex:(NSUInteger)pageIndex;
+- (BOOL)findPage:(NSUInteger *)pageIndexPtr location:(NSPoint *)pointPtr
forLine:(NSInteger)line inFile:(nullable NSString *)file;
+
+@end
+
NS_ASSUME_NONNULL_END
Modified: trunk/SKPDFSynchronizer.m
===================================================================
--- trunk/SKPDFSynchronizer.m 2024-04-03 16:34:12 UTC (rev 14174)
+++ trunk/SKPDFSynchronizer.m 2024-04-04 16:12:03 UTC (rev 14175)
@@ -37,56 +37,15 @@
*/
#import "SKPDFSynchronizer.h"
-#import "synctex_parser.h"
-#import "SKPDFSyncRecord.h"
+#import "SKSyncTeXParser.h"
+#import "SKPDFSyncParser.h"
#import "NSCharacterSet_SKExtensions.h"
-#import "NSScanner_SKExtensions.h"
-#import <CoreFoundation/CoreFoundation.h>
#import "NSFileManager_SKExtensions.h"
-#import "NSPointerFunctions_SKExtensions.h"
-#define PDFSYNC_TO_PDF(coord) ((CGFloat)coord / 65536.0)
-
-// Offset of coordinates in PDFKit and what pdfsync tells us. Don't know what
they are; is this implementation dependent?
-static NSPoint pdfOffset = {0.0, 0.0};
-
-#define SKPDFSynchronizerPdfsyncExtension @"pdfsync"
static NSArray *SKPDFSynchronizerTexExtensions = nil;
#pragma mark -
-@interface SKSyncTeX : NSObject {
- synctex_scanner_p scanner;
- NSMapTable *filenames;
-}
-
-- (instancetype)initWithFileName:(NSString *)fileName;
-
-@property (nonatomic, readonly) synctex_scanner_p scanner
NS_RETURNS_INNER_POINTER;
-@property (nonatomic, readonly) NSMapTable *filenames;
-
-- (BOOL)findFileLine:(NSInteger *)linePtr file:(out NSString * __autoreleasing
*)filePtr forLocation:(NSPoint)point inRect:(NSRect)rect
pageBounds:(NSRect)bounds atPageIndex:(NSUInteger)pageIndex;
-- (BOOL)findPage:(NSUInteger *)pageIndexPtr location:(NSPoint *)pointPtr
forLine:(NSInteger)line inFile:(NSString *)file;
-
-@end
-
-#pragma mark -
-
-@interface SKPDFSync : NSObject {
- NSMutableArray<NSMutableArray<SKPDFSyncRecord *> *> *pages;
- NSMapTable *lines;
-}
-
-@property (nonatomic, readonly) NSMutableArray<NSMutableArray<SKPDFSyncRecord
*> *> *pages;
-@property (nonatomic, readonly) NSMapTable *lines;
-
-- (BOOL)findFileLine:(NSInteger *)linePtr file:(out NSString * __autoreleasing
*)filePtr forLocation:(NSPoint)point inRect:(NSRect)rect
pageBounds:(NSRect)bounds atPageIndex:(NSUInteger)pageIndex;
-- (BOOL)findPage:(NSUInteger *)pageIndexPtr location:(NSPoint *)pointPtr
forLine:(NSInteger)line inFile:(NSString *)file;
-
-@end
-
-#pragma mark -
-
@implementation SKPDFSynchronizer
@synthesize delegate;
@@ -108,8 +67,8 @@
syncFileName = nil;
lastModDate = nil;
- pdfsync = nil;
- synctex = nil;
+ parser = nil;
+ sourceFileNames = nil;
shouldKeepRunning = YES;
@@ -178,9 +137,7 @@
#pragma mark Support
-- (NSString *)sourceFileForFileName:(NSString *)file isTeX:(BOOL)isTeX
removeQuotes:(BOOL)removeQuotes {
- if (removeQuotes && [file length] > 2 && [file characterAtIndex:0] == '"'
&& [file characterAtIndex:[file length] - 1] == '"')
- file = [file substringWithRange:NSMakeRange(1, [file length] - 2)];
+- (NSString *)sourceFileForFileName:(NSString *)file isTeX:(BOOL)isTeX {
if ([file isAbsolutePath] == NO)
file = [[[self fileName] stringByDeletingLastPathComponent]
stringByAppendingPathComponent:file];
if (isTeX && [fileManager fileExistsAtPath:file] == NO &&
[SKPDFSynchronizerTexExtensions containsObject:[[file pathExtension]
lowercaseString]] == NO) {
@@ -208,136 +165,22 @@
#pragma mark Loading sync file
-static inline SKPDFSyncRecord *recordForIndex(NSMapTable *records, NSInteger
recordIndex) {
- SKPDFSyncRecord *record = (__bridge SKPDFSyncRecord *)NSMapGet(records,
(void *)recordIndex);
- if (record == nil) {
- record = [[SKPDFSyncRecord alloc] initWithRecordIndex:recordIndex];
- NSMapInsert(records, (void *)recordIndex, (__bridge void *)record);
- }
- return record;
-}
-
-- (BOOL)loadPdfsyncFile:(NSString *)theFileName {
-
- pdfsync = [[SKPDFSync alloc] init];
- synctex = nil;
-
- [self setSyncFileName:theFileName];
-
- NSString *pdfsyncString = [NSString stringWithContentsOfFile:theFileName
encoding:NSUTF8StringEncoding error:NULL];
+- (BOOL)loadSyncFile:(BOOL)pdfSync forFileName:(NSString *)theFileName {
BOOL rv = NO;
-
- if ([pdfsyncString length]) {
-
- NSMapTable *records = [[NSMapTable alloc]
initWithKeyOptions:NSPointerFunctionsOpaqueMemory |
NSPointerFunctionsIntegerPersonality
valueOptions:NSPointerFunctionsStrongMemory |
NSPointerFunctionsObjectPersonality capacity:0];
- NSMutableArray *files = [[NSMutableArray alloc] init];
- NSString *file;
- NSInteger recordIndex, line, pageIndex;
- double x, y;
- SKPDFSyncRecord *record;
- unichar ch;
- NSScanner *sc = [[NSScanner alloc] initWithString:pdfsyncString];
- NSCharacterSet *newlines = [NSCharacterSet newlineCharacterSet];
-
- [sc setCharactersToBeSkipped:[NSCharacterSet whitespaceCharacterSet]];
-
- if ([sc scanUpToCharactersFromSet:newlines intoString:&file] &&
- [sc scanCharactersFromSet:newlines intoString:NULL]) {
-
- file = [self sourceFileForFileName:file isTeX:YES
removeQuotes:YES];
- [files addObject:file];
-
- [[pdfsync lines] setObject:[NSMutableArray array] forKey:file];
-
- // we ignore the version
- if ([sc scanString:@"version" intoString:NULL] && [sc
scanInteger:NULL]) {
-
- [sc scanCharactersFromSet:newlines intoString:NULL];
-
- while (atomic_load(&shouldKeepRunning) && [sc
scanCharacter:&ch]) {
-
- switch (ch) {
- case 'l':
- if ([sc scanInteger:&recordIndex] && [sc
scanInteger:&line]) {
- // we ignore the column
- [sc scanInteger:NULL];
- record = recordForIndex(records, recordIndex);
- [record setFile:file];
- [record setLine:line];
- [[[pdfsync lines] objectForKey:file]
addObject:record];
- }
- break;
- case 'p':
- // we ignore * and + modifiers
- if ([sc scanString:@"*" intoString:NULL] == NO)
- [sc scanString:@"+" intoString:NULL];
- if ([sc scanInteger:&recordIndex] && [sc
scanDouble:&x] && [sc scanDouble:&y]) {
- record = recordForIndex(records, recordIndex);
- [record setPageIndex:[[pdfsync pages] count] -
1];
- [record setPoint:NSMakePoint(PDFSYNC_TO_PDF(x)
+ pdfOffset.x, PDFSYNC_TO_PDF(y) + pdfOffset.y)];
- [[[pdfsync pages] lastObject]
addObject:record];
- }
- break;
- case 's':
- // start of a new page, the scanned integer should
always equal [[pdfsync pages] count]+1
- if ([sc scanInteger:&pageIndex] == NO) pageIndex =
[[pdfsync pages] count] + 1;
- while (pageIndex > (NSInteger)[[pdfsync pages]
count])
- [[pdfsync pages] addObject:[NSMutableArray
array]];
- break;
- case '(':
- // start of a new source file
- if ([sc scanUpToCharactersFromSet:newlines
intoString:&file]) {
- file = [self sourceFileForFileName:file
isTeX:YES removeQuotes:YES];
- [files addObject:file];
- if ([[pdfsync lines] objectForKey:file] == nil)
- [[pdfsync lines] setObject:[NSMutableArray
array] forKey:file];
- }
- break;
- case ')':
- // closing of a source file
- if ([files count]) {
- [files removeLastObject];
- file = [files lastObject];
- }
- break;
- default:
- // shouldn't reach
- break;
- }
-
- [sc scanUpToCharactersFromSet:newlines intoString:NULL];
- [sc scanCharactersFromSet:newlines intoString:NULL];
- }
-
- NSArray *lineSortDescriptors = @[[[NSSortDescriptor alloc]
initWithKey:@"line" ascending:YES]];
- NSArray *pointSortDescriptors = @[[[NSSortDescriptor alloc]
initWithKey:@"x" ascending:YES], [[NSSortDescriptor alloc] initWithKey:@"y"
ascending:NO]];
-
- for (NSMutableArray *array in [[pdfsync lines]
objectEnumerator])
- [array sortUsingDescriptors:lineSortDescriptors];
- [[pdfsync pages]
makeObjectsPerformSelector:@selector(sortUsingDescriptors:)
- withObject:pointSortDescriptors];
-
- rv = atomic_load(&shouldKeepRunning);
- }
- }
- }
-
- return rv;
-}
-
-- (BOOL)loadSynctexFileForFileName:(NSString *)theFileName {
- BOOL rv = NO;
- synctex = [[SKSyncTeX alloc] initWithFileName:theFileName];
- if (synctex) {
- const char *fileRep = synctex_scanner_get_synctex([synctex scanner]);
- [self setSyncFileName:[self sourceFileForFileName:[NSString
stringWithUTF8String:fileRep] isTeX:NO removeQuotes:NO]];
- pdfsync = nil;
- synctex_node_p node = synctex_scanner_input([synctex scanner]);
- do {
- if ((fileRep = synctex_scanner_get_name([synctex scanner],
synctex_node_tag(node)))) {
- NSMapInsert([synctex filenames], (__bridge void *)[self
sourceFileForFileName:[NSString stringWithUTF8String:fileRep] isTeX:YES
removeQuotes:NO], (void *)fileRep);
- }
- } while ((node = synctex_node_next(node)));
+ if (pdfSync)
+ parser = [[SKPDFSyncParser alloc] initWithFileName:theFileName];
+ else
+ parser = [[SKSyncTeXParser alloc] initWithFileName:theFileName];
+ if (parser) {
+ isPdfsync = pdfSync;
+ [self setSyncFileName:[self sourceFileForFileName:[parser
syncFileName] isTeX:NO]];
+ if (sourceFileNames == nil)
+ sourceFileNames = [[NSMutableDictionary alloc] init];
+ else
+ [sourceFileNames removeAllObjects];
+ [parser enumerateSourceFilesUsingBlock:^(NSString *file){
+ [sourceFileNames setObject:[self sourceFileForFileName:file
isTeX:YES] forKey:file];
+ }];
rv = atomic_load(&shouldKeepRunning);
}
return rv;
@@ -357,17 +200,14 @@
if (currentModDate && [modDate compare:currentModDate] !=
NSOrderedDescending)
rv = YES;
- else if (pdfsync)
- rv = [self loadPdfsyncFile:theSyncFileName];
- else
- rv = [self loadSynctexFileForFileName:theFileName];
+ else if (isPdfsync)
+ rv = [self loadSyncFile:YES forFileName:theSyncFileName];
+ if (rv == NO)
+ rv = [self loadSyncFile:NO forFileName:theFileName];
} else {
- rv = [self loadSynctexFileForFileName:theFileName];
- if (rv == NO) {
- theSyncFileName = [[theFileName stringByDeletingPathExtension]
stringByAppendingPathExtension:SKPDFSynchronizerPdfsyncExtension];
- if ([fileManager fileExistsAtPath:theSyncFileName])
- rv = [self loadPdfsyncFile:theSyncFileName];
- }
+ rv = [self loadSyncFile:NO forFileName:theFileName];
+ if (rv == NO)
+ rv = [self loadSyncFile:YES forFileName:theFileName];
}
}
if (rv == NO)
@@ -382,17 +222,10 @@
if (atomic_load(&shouldKeepRunning) && [self loadSyncFileIfNeeded]) {
NSInteger foundLine = 0;
NSString *foundFile = nil;
- BOOL success = NO;
+ BOOL success = [parser findFileLine:&foundLine file:&foundFile
forLocation:point inRect:rect pageBounds:bounds atPageIndex:pageIndex];
- if (pdfsync) {
- success = [pdfsync findFileLine:&foundLine file:&foundFile
forLocation:point inRect:rect pageBounds:bounds atPageIndex:pageIndex];
- } else {
- success = [synctex findFileLine:&foundLine file:&foundFile
forLocation:point inRect:rect pageBounds:bounds atPageIndex:pageIndex];
- if (success)
- foundFile = [self sourceFileForFileName:foundFile
isTeX:YES removeQuotes:NO];
- }
-
if (success && atomic_load(&shouldKeepRunning)) {
+ foundFile = [self sourceFileForFileName:foundFile isTeX:YES];
dispatch_async(dispatch_get_main_queue(), ^{
[delegate synchronizerFoundLine:foundLine
inFile:foundFile];
});
@@ -410,15 +243,22 @@
NSPoint foundPoint = NSZeroPoint;
SKPDFSynchronizerOption foundOptions = options;
BOOL success = NO;
- NSString *fixedFile = [self sourceFileForFileName:file isTeX:YES
removeQuotes:NO];
+ NSString *fixedFile = [self sourceFileForFileName:file isTeX:YES];
+ NSString *sourceFile = [sourceFileNames objectForKey:fixedFile] ?:
[sourceFileNames objectForKey:[[fixedFile stringByResolvingSymlinksInPath]
stringByStandardizingPath]];
+ if (sourceFile == nil) {
+ for (NSString *fn in sourceFileNames) {
+ if ([[fn lastPathComponent]
caseInsensitiveCompare:[fixedFile lastPathComponent]] == NSOrderedSame) {
+ sourceFile = [sourceFileNames objectForKey:fixedFile];
+ break;
+ }
+ }
+ if (sourceFile == nil)
+ sourceFile = [fixedFile lastPathComponent];
+ }
+ success = [parser findPage:&foundPageIndex location:&foundPoint
forLine:line inFile:sourceFile];
- if (pdfsync)
- success = [pdfsync findPage:&foundPageIndex
location:&foundPoint forLine:line inFile:fixedFile];
- else
- success = [synctex findPage:&foundPageIndex
location:&foundPoint forLine:line inFile:fixedFile];
-
if (success && atomic_load(&shouldKeepRunning)) {
- if (pdfsync)
+ if (isPdfsync)
foundOptions &= ~SKPDFSynchronizerFlippedMask;
else
foundOptions |= SKPDFSynchronizerFlippedMask;
@@ -431,206 +271,3 @@
}
@end
-
-#pragma mark -
-
-@implementation SKSyncTeX
-
-@synthesize scanner, filenames;
-
-- (instancetype)initWithFileName:(NSString *)fileName {
- self = [super init];
- if (self) {
- scanner = synctex_scanner_new_with_output_file([fileName UTF8String],
NULL, 1);
- if (scanner) {
- NSPointerFunctions *keyPointerFunctions = [NSPointerFunctions
caseInsensitiveStringPointerFunctions];
- NSPointerFunctions *valuePointerFunctions = [NSPointerFunctions
pointerFunctionsWithOptions:NSPointerFunctionsMallocMemory |
NSPointerFunctionsCStringPersonality | NSPointerFunctionsCopyIn];
- filenames = [[NSMapTable alloc]
initWithKeyPointerFunctions:keyPointerFunctions
valuePointerFunctions:valuePointerFunctions capacity:0];
- } else {
- self = nil;
- }
- }
- return self;
-}
-
-- (void)dealloc {
- if (scanner) synctex_scanner_free(scanner);
- scanner = NULL;
-}
-
-- (BOOL)findFileLine:(NSInteger *)linePtr file:(out NSString * __autoreleasing
*)filePtr forLocation:(NSPoint)point inRect:(NSRect)rect
pageBounds:(NSRect)bounds atPageIndex:(NSUInteger)pageIndex {
- BOOL rv = NO;
- if (synctex_edit_query(scanner, (int)pageIndex + 1, point.x,
NSMaxY(bounds) - point.y) > 0) {
- synctex_node_p node;
- const char *file;
- while (rv == NO && (node = synctex_scanner_next_result(scanner))) {
- if ((file = synctex_scanner_get_name(scanner,
synctex_node_tag(node)))) {
- *linePtr = MAX(synctex_node_line(node), 1) - 1;
- *filePtr = [NSString stringWithUTF8String:file];
- rv = YES;
- }
- }
- }
- if (rv == NO)
- NSLog(@"SyncTeX was unable to find file and line.");
- return rv;
-}
-
-- (BOOL)findPage:(NSUInteger *)pageIndexPtr location:(NSPoint *)pointPtr
forLine:(NSInteger)line inFile:(NSString *)file {
- BOOL rv = NO;
- char *filename = (char *)NSMapGet(filenames, (__bridge void *)file) ?:
(char *)NSMapGet(filenames, (__bridge void *)[[file
stringByResolvingSymlinksInPath] stringByStandardizingPath]);
- if (filename == NULL) {
- for (NSString *fn in filenames) {
- if ([[fn lastPathComponent] caseInsensitiveCompare:[file
lastPathComponent]] == NSOrderedSame) {
- filename = (char *)NSMapGet(filenames, (__bridge void *)file);
- break;
- }
- }
- if (filename == NULL)
- filename = (char *)[[file lastPathComponent] UTF8String];
- }
- if (synctex_display_query(scanner, filename, (int)line + 1, 0, -1) > 0) {
- synctex_node_p node = synctex_scanner_next_result(scanner);
- if (node) {
- NSUInteger page = synctex_node_page(node);
- *pageIndexPtr = MAX(page, 1ul) - 1;
- *pointPtr = NSMakePoint(synctex_node_visible_h(node),
synctex_node_visible_v(node));
- rv = YES;
- }
- }
- if (rv == NO)
- NSLog(@"SyncTeX was unable to find location and page.");
- return rv;
-}
-
-@end
-
-#pragma mark -
-
-@implementation SKPDFSync
-
-@synthesize pages, lines;
-
-- (instancetype)init {
- self = [super init];
- if (self) {
- pages = [[NSMutableArray alloc] init];
- lines = [[NSMapTable alloc]
initWithKeyPointerFunctions:[NSPointerFunctions
caseInsensitiveStringPointerFunctions]
valuePointerFunctions:[NSPointerFunctions strongPointerFunctions] capacity:0];
- }
- return self;
-}
-
-- (BOOL)findFileLine:(NSInteger *)linePtr file:(out NSString * __autoreleasing
*)filePtr forLocation:(NSPoint)point inRect:(NSRect)rect
pageBounds:(NSRect)bounds atPageIndex:(NSUInteger)pageIndex {
- BOOL rv = NO;
- if (pageIndex < [pages count]) {
-
- SKPDFSyncRecord *record = nil;
- SKPDFSyncRecord *beforeRecord = nil;
- SKPDFSyncRecord *afterRecord = nil;
- NSMutableDictionary *atRecords = [NSMutableDictionary dictionary];
-
- for (record in [pages objectAtIndex:pageIndex]) {
- if ([record line] == 0)
- continue;
- NSPoint p = [record point];
- if (p.y > NSMaxY(rect)) {
- beforeRecord = record;
- } else if (p.y < NSMinY(rect)) {
- afterRecord = record;
- break;
- } else if (p.x < NSMinX(rect)) {
- beforeRecord = record;
- } else if (p.x > NSMaxX(rect)) {
- afterRecord = record;
- break;
- } else {
- [atRecords setObject:record forKey:[NSNumber
numberWithDouble:fabs(p.x - point.x)]];
- }
- }
-
- record = nil;
- if ([atRecords count]) {
- NSNumber *nearest = [[[atRecords allKeys]
sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:0];
- record = [atRecords objectForKey:nearest];
- } else if (beforeRecord && afterRecord) {
- NSPoint beforePoint = [beforeRecord point];
- NSPoint afterPoint = [afterRecord point];
- if (beforePoint.y - point.y < point.y - afterPoint.y)
- record = beforeRecord;
- else if (beforePoint.y - point.y > point.y - afterPoint.y)
- record = afterRecord;
- else if (beforePoint.x - point.x < point.x - afterPoint.x)
- record = beforeRecord;
- else if (beforePoint.x - point.x > point.x - afterPoint.x)
- record = afterRecord;
- else
- record = beforeRecord;
- } else if (beforeRecord) {
- record = beforeRecord;
- } else if (afterRecord) {
- record = afterRecord;
- }
-
- if (record) {
- *linePtr = [record line];
- *filePtr = [record file];
- rv = YES;
- }
- }
- if (rv == NO)
- NSLog(@"PDFSync was unable to find file and line.");
- return rv;
-}
-
-- (BOOL)findPage:(NSUInteger *)pageIndexPtr location:(NSPoint *)pointPtr
forLine:(NSInteger)line inFile:(NSString *)file {
- BOOL rv = NO;
- NSArray *theLines = [lines objectForKey:file];
- if (theLines) {
-
- SKPDFSyncRecord *record = nil;
- SKPDFSyncRecord *beforeRecord = nil;
- SKPDFSyncRecord *afterRecord = nil;
- SKPDFSyncRecord *atRecord = nil;
-
- for (record in theLines) {
- if ([record pageIndex] == NSNotFound)
- continue;
- NSInteger l = [record line];
- if (l < line) {
- beforeRecord = record;
- } else if (l > line) {
- afterRecord = record;
- break;
- } else {
- atRecord = record;
- break;
- }
- }
-
- if (atRecord) {
- record = atRecord;
- } else if (beforeRecord && afterRecord) {
- NSInteger beforeLine = [beforeRecord line];
- NSInteger afterLine = [afterRecord line];
- if (beforeLine - line > line - afterLine)
- record = afterRecord;
- else
- record = beforeRecord;
- } else if (beforeRecord) {
- record = beforeRecord;
- } else if (afterRecord) {
- record = afterRecord;
- }
-
- if (record) {
- *pageIndexPtr = [record pageIndex];
- *pointPtr = [record point];
- rv = YES;
- }
- }
- if (rv == NO)
- NSLog(@"PDFSync was unable to find location and page.");
- return rv;
-}
-
-@end
Added: trunk/SKSyncTeXParser.h
===================================================================
--- trunk/SKSyncTeXParser.h (rev 0)
+++ trunk/SKSyncTeXParser.h 2024-04-04 16:12:03 UTC (rev 14175)
@@ -0,0 +1,51 @@
+//
+// SKSyncTeXParser.h
+// Skim
+//
+// Created by Christiaan Hofman on 04/04/2024.
+/*
+ This software is Copyright (c) 2024
+ 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 "SKPDFSynchronizer.h"
+#import "synctex_parser.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface SKSyncTeXParser : NSObject <SKSyncParser> {
+ synctex_scanner_p scanner;
+}
+
+@end
+
+NS_ASSUME_NONNULL_END
Added: trunk/SKSyncTeXParser.m
===================================================================
--- trunk/SKSyncTeXParser.m (rev 0)
+++ trunk/SKSyncTeXParser.m 2024-04-04 16:12:03 UTC (rev 14175)
@@ -0,0 +1,112 @@
+//
+// SKSyncTeXParser.m
+// Skim
+//
+// Created by Christiaan Hofman on 04/04/2024.
+/*
+ This software is Copyright (c) 2024
+ 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 "SKSyncTeXParser.h"
+
+
+@implementation SKSyncTeXParser
+
+@dynamic syncFileName;
+
+- (instancetype)initWithFileName:(NSString *)fileName {
+ self = [super init];
+ if (self) {
+ scanner = synctex_scanner_new_with_output_file([fileName UTF8String],
NULL, 1);
+ if (scanner == NULL) {
+ self = nil;
+ }
+ }
+ return self;
+}
+
+- (void)dealloc {
+ if (scanner) synctex_scanner_free(scanner);
+ scanner = NULL;
+}
+
+- (NSString *)syncFileName {
+ const char *fileRep = synctex_scanner_get_synctex(scanner);
+ return [NSString stringWithUTF8String:fileRep];
+}
+
+- (void)enumerateSourceFilesUsingBlock:(void (^)(NSString *file))block {
+ const char *fileRep;
+ synctex_node_p node = synctex_scanner_input(scanner);
+ do {
+ if ((fileRep = synctex_scanner_get_name(scanner,
synctex_node_tag(node)))) {
+ block([NSString stringWithUTF8String:fileRep]);
+ }
+ } while ((node = synctex_node_next(node)));
+}
+
+- (BOOL)findFileLine:(NSInteger *)linePtr file:(NSString * __autoreleasing
*)filePtr forLocation:(NSPoint)point inRect:(NSRect)rect
pageBounds:(NSRect)bounds atPageIndex:(NSUInteger)pageIndex {
+ BOOL rv = NO;
+ if (synctex_edit_query(scanner, (int)pageIndex + 1, point.x,
NSMaxY(bounds) - point.y) > 0) {
+ synctex_node_p node;
+ const char *file;
+ while (rv == NO && (node = synctex_scanner_next_result(scanner))) {
+ if ((file = synctex_scanner_get_name(scanner,
synctex_node_tag(node)))) {
+ *linePtr = MAX(synctex_node_line(node), 1) - 1;
+ *filePtr = [NSString stringWithUTF8String:file];
+ rv = YES;
+ }
+ }
+ }
+ if (rv == NO)
+ NSLog(@"SyncTeX was unable to find file and line.");
+ return rv;
+}
+
+- (BOOL)findPage:(NSUInteger *)pageIndexPtr location:(NSPoint *)pointPtr
forLine:(NSInteger)line inFile:(NSString *)file {
+ BOOL rv = NO;
+ const char *filename = [file UTF8String];
+ if (synctex_display_query(scanner, filename, (int)line + 1, 0, -1) > 0) {
+ synctex_node_p node = synctex_scanner_next_result(scanner);
+ if (node) {
+ NSUInteger page = synctex_node_page(node);
+ *pageIndexPtr = MAX(page, 1ul) - 1;
+ *pointPtr = NSMakePoint(synctex_node_visible_h(node),
synctex_node_visible_v(node));
+ rv = YES;
+ }
+ }
+ if (rv == NO)
+ NSLog(@"SyncTeX was unable to find location and page.");
+ return rv;
+}
+
+@end
Modified: trunk/Skim.xcodeproj/project.pbxproj
===================================================================
--- trunk/Skim.xcodeproj/project.pbxproj 2024-04-03 16:34:12 UTC (rev
14174)
+++ trunk/Skim.xcodeproj/project.pbxproj 2024-04-04 16:12:03 UTC (rev
14175)
@@ -237,6 +237,8 @@
CEBC0DDD2791C607008686E8 /* NSObject_SKExtensions.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CEBC0DDC2791C607008686E8 /*
NSObject_SKExtensions.m */; };
CEBCA4C02868A93A00E6376E /* SKLine.m in Sources */ = {isa =
PBXBuildFile; fileRef = CEBCA4BF2868A93A00E6376E /* SKLine.m */; };
CEBD52ED0C9C0AE500FBF6A4 /* SKBookmark.m in Sources */ = {isa =
PBXBuildFile; fileRef = CEBD52EB0C9C0AE500FBF6A4 /* SKBookmark.m */; };
+ CEC1B0432BBF00D8006786B0 /* SKSyncTeXParser.m in Sources */ =
{isa = PBXBuildFile; fileRef = CEC1B0422BBF00D8006786B0 /* SKSyncTeXParser.m
*/; };
+ CEC1B0602BBF03AB006786B0 /* SKPDFSyncParser.m in Sources */ =
{isa = PBXBuildFile; fileRef = CEC1B05F2BBF03AB006786B0 /* SKPDFSyncParser.m
*/; };
CEC29533275A66A2000F2D4C /* SKNotePrefs.m in Sources */ = {isa
= PBXBuildFile; fileRef = CEC29532275A66A2000F2D4C /* SKNotePrefs.m */; };
CEC29536275A7D58000F2D4C /* SKPreferencesCommand.m in Sources
*/ = {isa = PBXBuildFile; fileRef = CEC29535275A7D58000F2D4C /*
SKPreferencesCommand.m */; };
CEC3AD240E23EC0300F40B0B /* PDFAnnotationLink_SKExtensions.m in
Sources */ = {isa = PBXBuildFile; fileRef = CEC3AD230E23EC0300F40B0B /*
PDFAnnotationLink_SKExtensions.m */; };
@@ -1151,6 +1153,10 @@
CEBCA4BF2868A93A00E6376E /* SKLine.m */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SKLine.m;
sourceTree = "<group>"; };
CEBD52EA0C9C0AE500FBF6A4 /* SKBookmark.h */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path =
SKBookmark.h; sourceTree = "<group>"; };
CEBD52EB0C9C0AE500FBF6A4 /* SKBookmark.m */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path
= SKBookmark.m; sourceTree = "<group>"; };
+ CEC1B0412BBF00D8006786B0 /* SKSyncTeXParser.h */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SKSyncTeXParser.h;
sourceTree = "<group>"; };
+ CEC1B0422BBF00D8006786B0 /* SKSyncTeXParser.m */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path =
SKSyncTeXParser.m; sourceTree = "<group>"; };
+ CEC1B05E2BBF03AB006786B0 /* SKPDFSyncParser.h */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SKPDFSyncParser.h;
sourceTree = "<group>"; };
+ CEC1B05F2BBF03AB006786B0 /* SKPDFSyncParser.m */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path =
SKPDFSyncParser.m; sourceTree = "<group>"; };
CEC29531275A66A2000F2D4C /* SKNotePrefs.h */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SKNotePrefs.h;
sourceTree = "<group>"; };
CEC29532275A66A2000F2D4C /* SKNotePrefs.m */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SKNotePrefs.m;
sourceTree = "<group>"; };
CEC29534275A7D58000F2D4C /* SKPreferencesCommand.h */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.c.h; path =
SKPreferencesCommand.h; sourceTree = "<group>"; };
@@ -1990,6 +1996,10 @@
CE5FA1660C909886008BE480 /* SKFDFParser.m */,
CE1E2B260BDAB6180011D9DD /* SKPDFSynchronizer.h
*/,
CE1E2B270BDAB6180011D9DD /* SKPDFSynchronizer.m
*/,
+ CEC1B0412BBF00D8006786B0 /* SKSyncTeXParser.h
*/,
+ CEC1B0422BBF00D8006786B0 /* SKSyncTeXParser.m
*/,
+ CEC1B05E2BBF03AB006786B0 /* SKPDFSyncParser.h
*/,
+ CEC1B05F2BBF03AB006786B0 /* SKPDFSyncParser.m
*/,
CE48BAD50C089EA300A166C6 /* SKTemplateParser.h
*/,
CE48BAD60C089EA300A166C6 /* SKTemplateParser.m
*/,
);
@@ -2800,6 +2810,7 @@
CEFDF8BE0B3848C40091C61A /*
SKNavigationWindow.m in Sources */,
45A3BD080B4F0770002B297F /* SKStringConstants.m
in Sources */,
CE3A3D2C0B78C0A0006B64D3 /*
SKNPDFAnnotationNote_SKExtensions.m in Sources */,
+ CEC1B0602BBF03AB006786B0 /* SKPDFSyncParser.m
in Sources */,
CE3A41580B790C56006B64D3 /* SKDragImageView.m
in Sources */,
CE3A45530B7A04A4006B64D3 /*
NSBezierPath_SKExtensions.m in Sources */,
CEBCA4C02868A93A00E6376E /* SKLine.m in Sources
*/,
@@ -2959,6 +2970,7 @@
CE4E1E9A12BCFF5A005227ED /* HIDRemote.m in
Sources */,
CE171E3512C3AC1600291179 /*
SKFileUpdateChecker.m in Sources */,
CEECD61C12E9E30B00B9E35E /*
NSError_SKExtensions.m in Sources */,
+ CEC1B0432BBF00D8006786B0 /* SKSyncTeXParser.m
in Sources */,
CE12A73E134F215F003AED67 /* SKSelectCommand.m
in Sources */,
CE030C6113C07A57007A47E9 /*
PDFView_SKExtensions.m in Sources */,
CEB402C313EDAD6100851D1B /* SKTemporaryData.m
in Sources */,
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