Revision: 22016
          http://sourceforge.net/p/bibdesk/svn/22016
Author:   hofman
Date:     2018-02-23 15:44:34 +0000 (Fri, 23 Feb 2018)
Log Message:
-----------
Implement some generic part of web parser handlers in abstract superclasses, to 
void repeating the same thing (mainly error handling), and making sure the 
delegate methods are properly called

Modified Paths:
--------------
    trunk/bibdesk/BDSKArxivParser.m
    trunk/bibdesk/BDSKAsynchronousWebParser.h
    trunk/bibdesk/BDSKAsynchronousWebParser.m
    trunk/bibdesk/BDSKBibTeXWebParser.m
    trunk/bibdesk/BDSKCOinSParser.m
    trunk/bibdesk/BDSKHCiteParser.m
    trunk/bibdesk/BDSKHubmedParser.m
    trunk/bibdesk/BDSKIACRParser.m
    trunk/bibdesk/BDSKIEEEXploreParser.m
    trunk/bibdesk/BDSKInspireParser.m
    trunk/bibdesk/BDSKJSTORWebParser.m
    trunk/bibdesk/BDSKLinkedBibTeXParser.m
    trunk/bibdesk/BDSKMASParser.m
    trunk/bibdesk/BDSKMathSciNetParser.m
    trunk/bibdesk/BDSKNumdamParser.m
    trunk/bibdesk/BDSKProjectEuclidParser.m
    trunk/bibdesk/BDSKWebParser.h
    trunk/bibdesk/BDSKWebParser.m
    trunk/bibdesk/BDSKZentralblattParser.m
    trunk/bibdesk/English.lproj/Localizable.strings
    trunk/bibdesk/French.lproj/Localizable.strings
    trunk/bibdesk/German.lproj/Localizable.strings

Modified: trunk/bibdesk/BDSKArxivParser.m
===================================================================
--- trunk/bibdesk/BDSKArxivParser.m     2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKArxivParser.m     2018-02-23 15:44:34 UTC (rev 22016)
@@ -39,7 +39,6 @@
 #import "BDSKArxivParser.h"
 #import "BibItem.h"
 #import "BDSKLinkedFile.h"
-#import "NSError_BDSKExtensions.h"
 #import "NSXMLNode_BDSKExtensions.h"
 #import <AGRegex/AGRegex.h>
 
@@ -68,7 +67,7 @@
 // A potential enhancement would be to recognize documents that are index 
lists of citations
 // and follow links two levels deep to get bibitems from each citation in the 
list.
 
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
 
     NSURL *url = [self URL];
     
@@ -110,13 +109,11 @@
     AGRegex *journalRegex3 = [AGRegex 
regexWithPattern:@"(.+[^0-9])([0-9]+):(.*),([0-9]{4})"
                                                options:AGRegexMultiline];
     
-    NSError *searchError = nil;
-            
     // fetch the arxiv search results
     NSArray *arxivSearchResults = nil;
     NSXMLElement *rootElement = [[self xmlDocument] rootElement];
     
-    arxivSearchResults = [rootElement nodesForXPath:arxivSearchResultNodePath 
error:&searchError];
+    arxivSearchResults = [rootElement nodesForXPath:arxivSearchResultNodePath 
error:outError];
     
     NSMutableArray *items = [NSMutableArray arrayWithCapacity:0];
 
@@ -275,13 +272,8 @@
         [item release];
         
     }
-        
-    if (0 == [items count] && searchError == nil) {
-        searchError = [NSError mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
-        [searchError setValue:NSLocalizedString(@"Unable to parse this page.  
Please report this to BibDesk's developers and provide the URL.", @"Web parser 
error") forKey:NSLocalizedRecoverySuggestionErrorKey];
-    }
     
-    [self didFinishStartingFindingItems:items withSuccess:[items count] > 0 
error:searchError];
+    return items;
 }
 
 

Modified: trunk/bibdesk/BDSKAsynchronousWebParser.h
===================================================================
--- trunk/bibdesk/BDSKAsynchronousWebParser.h   2018-02-23 07:30:46 UTC (rev 
22015)
+++ trunk/bibdesk/BDSKAsynchronousWebParser.h   2018-02-23 15:44:34 UTC (rev 
22016)
@@ -48,33 +48,14 @@
 #pragma mark -
 
 @interface BDSKAsynchronousWebParser : BDSKWebParser 
<BDSKCitationDownloadDelegate> {
-    BOOL finishedAddingDownloads;
     NSMutableArray *downloads;
 }
 
-// subclasses should set this when all downloads are added
-@property (nonatomic) BOOL finishedAddingDownloads;
-// whether the parser can finish, checks finishedAddingDownloads and no active 
downloads
-@property (nonatomic, readonly) BOOL canFinish;
-
-// starts the download immediately after adding
-- (void)addDownload:(BDSKCitationDownload *)download;
-// subclasses should call this at the end of the download callback
-- (void)removeDownload:(BDSKCitationDownload *)download;
-
-// start should finish when it ends without downloads
-
-// don't call super
-// subclasses should remove the download
-// make sure subclasses finish when there are no further downloads
-- (void)downloadDidFinish:(BDSKCitationDownload *)download;
-
-// convenience method to add a new download
+// subclasses can add downloads in -itemsReturningError:
 - (void)addDownloadWithRequest:(NSURLRequest *)request 
contextInfo:(id)contextInfo;
 
-// convenience method to remove the download and call the various delegate 
methods if needed
-// subclasses can use this at the end of downloadDidFinish: instead of calling 
the delegate methods
-- (void)didFinishDownload:(BDSKCitationDownload *)download 
findingItems:(NSArray *)items withSuccess:(BOOL)success error:(NSError *)error;
+// main method for subclasses to implement, together with -itemsReturningError:
+- (NSArray *)itemsFromDownload:(BDSKCitationDownload *)download error:(NSError 
**)outError;
 
 @end
 

Modified: trunk/bibdesk/BDSKAsynchronousWebParser.m
===================================================================
--- trunk/bibdesk/BDSKAsynchronousWebParser.m   2018-02-23 07:30:46 UTC (rev 
22015)
+++ trunk/bibdesk/BDSKAsynchronousWebParser.m   2018-02-23 15:44:34 UTC (rev 
22016)
@@ -37,29 +37,17 @@
  */
 
 #import "BDSKAsynchronousWebParser.h"
+#import "BibItem.h"
+#import "NSError_BDSKExtensions.h"
 
 
 @implementation BDSKAsynchronousWebParser
 
-@synthesize finishedAddingDownloads;
-@dynamic canFinish;
-
 - (void)dealloc {
     BDSKDESTROY(downloads);
     [super dealloc];
 }
 
-- (void)addDownload:(BDSKCitationDownload *)download {
-    if (downloads == nil)
-        downloads = [[NSMutableArray alloc] init];
-    [downloads addObject:download];
-    [download start];
-}
-
-- (void)removeDownload:(BDSKCitationDownload *)download {
-    [downloads removeObject:download];
-}
-
 - (void)cancel {
     [super cancel];
     [downloads makeObjectsPerformSelector:@selector(cancel)];
@@ -67,37 +55,64 @@
 }
 
 - (BOOL)canFinish {
-    return [self finishedAddingDownloads] && [downloads count] == 0;
+    return [self finishedStarting] && [downloads count] == 0;
 }
 
+- (BOOL)succeededWithItems:(NSArray *)items {
+    return [items count] > 0 || downloads != nil;
+}
+
 - (void)downloadDidFinish:(BDSKCitationDownload *)download {
-    [self didFinishDownload:download findingItems:nil withSuccess:YES 
error:nil];
+    NSArray *items = nil;
+    NSError *error = [download error];
+    
+    if ([download failed] == NO)
+        items = [self itemsFromDownload:download error:&error];
+    
+    if ([items count] == 0) {
+        // display a fake item in the table so the user knows one of the items 
failed to parse, but still gets the rest of the data
+        NSString *errMsg = [error localizedDescription];
+        if (errMsg == nil)
+            errMsg = NSLocalizedString(@"Unable to parse as BibTeX", @"Web 
parser error");
+        NSMutableDictionary *pubFields = [NSMutableDictionary 
dictionaryWithObjectsAndKeys:errMsg, BDSKTitleString, nil];
+        NSString *string = [download string];
+        if ([download URL])
+            [pubFields setObject:[[download URL] absoluteString] 
forKey:BDSKUrlString];
+        if ([error localizedRecoverySuggestion])
+            [pubFields setObject:[error localizedRecoverySuggestion] 
forKey:BDSKAbstractString];
+        if (string)
+            [pubFields setObject:string forKey:BDSKAnnoteString];
+        BibItem *errorItem = [[BibItem alloc] initWithType:BDSKMiscString 
citeKey:nil pubFields:pubFields isNew:YES];
+        items = [NSArray arrayWithObjects:errorItem, nil];
+        [errorItem release];
+    }
+    
+    if ([items count] > 0)
+        [[self delegate] webParser:self didFindItems:items];
+    
+    [downloads removeObject:download];
+
+    if ([self canFinish])
+        [[self delegate] webParser:self didFinishWithSuccess:YES error:nil];
 }
 
 - (void)addDownloadWithRequest:(NSURLRequest *)request 
contextInfo:(id)contextInfo {
     BDSKCitationDownload *download = [[BDSKCitationDownload alloc] 
initWithRequest:request delegate:self];
+    
     if (contextInfo)
         [download setContextInfo:contextInfo];
-    [self addDownload:download];
+    
+    if (downloads == nil)
+        downloads = [[NSMutableArray alloc] init];
+    [downloads addObject:download];
+    
+    [download start];
+    
     [download release];
 }
 
-- (void)didFinishStartingFindingItems:(NSArray *)items 
withSuccess:(BOOL)success error:(NSError *)error {
-    if ([items count] > 0)
-        [[self delegate] webParser:self didFindItems:items];
-    [self setFinishedAddingDownloads:YES];
-    if ([self canFinish])
-        [[self delegate] webParser:self didFinishWithSuccess:success 
error:error];
-}
+- (NSArray *)itemsFromDownload:(BDSKCitationDownload *)download error:(NSError 
**)outError { return nil; }
 
-- (void)didFinishDownload:(BDSKCitationDownload *)download 
findingItems:(NSArray *)items withSuccess:(BOOL)success error:(NSError *)error {
-    if ([items count] > 0)
-        [[self delegate] webParser:self didFindItems:items];
-    [self removeDownload:download];
-    if ([self canFinish])
-        [[self delegate] webParser:self didFinishWithSuccess:success 
error:error];
-}
-
 @end
 
 #pragma mark -

Modified: trunk/bibdesk/BDSKBibTeXWebParser.m
===================================================================
--- trunk/bibdesk/BDSKBibTeXWebParser.m 2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKBibTeXWebParser.m 2018-02-23 15:44:34 UTC (rev 22016)
@@ -39,7 +39,6 @@
 #import "BDSKBibTeXWebParser.h"
 #import "BDSKBibTeXParser.h"
 #import "BibItem.h"
-#import "NSError_BDSKExtensions.h"
 #import "NSXMLNode_BDSKExtensions.h"
 #import <AGRegex/AGRegex.h>
 
@@ -69,12 +68,12 @@
        
 }
 
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
     
     NSMutableArray *items = [NSMutableArray array];
     NSString *mayContainBibtexXPath = @"./body//*/text()[contains(.,'@')]/..";
     NSError *error = nil;
-    NSArray *nodes = [[xmlDocument rootElement] 
nodesForXPath:mayContainBibtexXPath error:&error];
+    NSArray *nodes = [[xmlDocument rootElement] 
nodesForXPath:mayContainBibtexXPath error:outError];
     
     if ([nodes count] > 0) {
         // get a list of all things that might be the beginnings of a BibTeX 
item
@@ -95,7 +94,7 @@
         }
        }
        
-    [self didFinishStartingFindingItems:items withSuccess:[items count] > 0 
error:error];
+    return items;
 }
 
 + (NSDictionary *)parserInfo {

Modified: trunk/bibdesk/BDSKCOinSParser.m
===================================================================
--- trunk/bibdesk/BDSKCOinSParser.m     2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKCOinSParser.m     2018-02-23 15:44:34 UTC (rev 22016)
@@ -42,7 +42,6 @@
 #import "NSXMLNode_BDSKExtensions.h"
 #import "BDSKLinkedFile.h"
 #import "NSString_BDSKExtensions.h"
-#import "NSError_BDSKExtensions.h"
 
 /*
  The COinS or Z3988 format is a microformat which is embedded in web pages to 
include bibliographic information there.
@@ -311,35 +310,23 @@
 }
 
 // Process the document. 
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
 
        NSError *error;
-    NSArray *nodes = [[[self xmlDocument] rootElement] 
nodesForXPath:@".//span[@class='Z3988']" error:&error];
+    NSArray *nodes = [[[self xmlDocument] rootElement] 
nodesForXPath:@".//span[@class='Z3988']" error:outError];
     
-    NSMutableArray *results = nil;
+    NSMutableArray *items = [NSMutableArray arrayWithCapacity:[nodes count]];
     
-    if (0 == [nodes count]) {
-        // bail out with an XML error if the Xpath query fails
-        if (error == nil) {
-            error = [NSError mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
-            [error setValue:NSLocalizedString(@"Unable to parse this page.  
Please report this to BibDesk's developers and provide the URL.", @"Web parser 
error") forKey:NSLocalizedRecoverySuggestionErrorKey];
-        }
-        
-    } else {
-
-        results = [NSMutableArray arrayWithCapacity:[nodes count]];
-        
-        for (NSXMLNode *node in nodes) {
-            NSString *title;
-            BibItem *bibItem;
-            if ([node kind] == NSXMLElementKind &&
-                (title = [[(NSXMLElement *)node attributeForName:@"title"] 
XMLString]) &&
-                (bibItem = [BDSKCOinSParser parseCOinSString:title]))
-                [results addObject:bibItem];
-        }
+    for (NSXMLNode *node in nodes) {
+        NSString *title;
+        BibItem *bibItem;
+        if ([node kind] == NSXMLElementKind &&
+            (title = [[(NSXMLElement *)node attributeForName:@"title"] 
XMLString]) &&
+            (bibItem = [BDSKCOinSParser parseCOinSString:title]))
+            [items addObject:bibItem];
     }
     
-    [self didFinishStartingFindingItems:results withSuccess:[results count] != 
0 error:error];
+    return items;
 }
 
 // Array with feature description dictionary for the COinS microformat.

Modified: trunk/bibdesk/BDSKHCiteParser.m
===================================================================
--- trunk/bibdesk/BDSKHCiteParser.m     2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKHCiteParser.m     2018-02-23 15:44:34 UTC (rev 22016)
@@ -40,7 +40,6 @@
 #import "BibItem.h"
 #import "BDSKTypeManager.h"
 #import "NSXMLNode_BDSKExtensions.h"
-#import "NSError_BDSKExtensions.h"
 
 
 @interface BDSKHCiteParser (Private)
@@ -60,15 +59,13 @@
     return [[[xmlDocument rootElement] nodesForXPath:containsCitationPath 
error:&error] count] > 0;
 }
 
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
 
     NSMutableArray *items = [NSMutableArray arrayWithCapacity:0];
     
     NSString *containsCitationPath = @"./body//*[contains(concat(' ', 
normalize-space(@class), ' '),' hcite ')]";
 
-    NSError *error = nil;    
-
-    NSArray *mainNodes = [[[self xmlDocument] rootElement] 
nodesForXPath:containsCitationPath error:&error];
+    NSArray *mainNodes = [[[self xmlDocument] rootElement] 
nodesForXPath:containsCitationPath error:outError];
     
     
     for (NSXMLNode *obj in mainNodes) {
@@ -85,13 +82,8 @@
                                                  isNew:YES] autorelease];
         [items addObject:item];
     }
-        
-    if ([items count] == 0 && error == nil) {
-        error = [NSError mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
-        [error setValue:NSLocalizedString(@"Unable to parse this page.  Please 
report this to BibDesk's developers and provide the URL.", @"Web parser error") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-    }
-
-    [self didFinishStartingFindingItems:items withSuccess:[items count] > 0 
error:error];
+    
+    return items;
 }
 
 - (NSMutableDictionary *)dictionaryFromCitationNode:(NSXMLNode *)citationNode{

Modified: trunk/bibdesk/BDSKHubmedParser.m
===================================================================
--- trunk/bibdesk/BDSKHubmedParser.m    2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKHubmedParser.m    2018-02-23 15:44:34 UTC (rev 22016)
@@ -58,7 +58,7 @@
     return nil != [regex findInString:[url query]];
 }
 
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
 
     // query is 'uids=<somenumber>':
     //    NSString *uidString = [[url query] substringWithRange:NSMakeRange(5, 
[[url query] length] - 5)];
@@ -65,12 +65,8 @@
     NSURL *url = [self URL];
     AGRegex *regex = [AGRegex regexWithPattern:@".*uids=([0-9]+).*"];
     AGRegexMatch *match = [regex findInString:[url query]];
-    NSError *error = nil;
     
-    if (match == nil) {
-        error = [NSError mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
-        [error setValue:NSLocalizedString(@"Unable to parse this page.  Please 
report this to BibDesk's developers and provide the URL.", @"Web parser error") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-    } else {
+    if (match) {
         NSString *uidString = [match groupAtIndex:1];
         
         NSURL *btURL = [NSURL URLWithString:[NSString 
stringWithFormat:@"http://%@/export/bibtex.cgi?uids=%@&format=.txt";, [url 
host], uidString]];
@@ -82,34 +78,32 @@
         [self addDownloadWithRequest:request contextInfo:linkedURLString];
     }
     
-    [self didFinishStartingFindingItems:nil withSuccess:error == nil 
error:error];
+    return nil;
 }
 
-- (void)downloadDidFinish:(BDSKCitationDownload *)download {
+- (NSArray *)itemsFromDownload:(BDSKCitationDownload *)download error:(NSError 
**)outError {
     NSString *bibTeXString = [download string];
     NSError *error = [download error];
     NSArray *items = nil;
+    NSArray *bibtexItems = nil;
     
-    if ([download failed] == NO) {
+    if (bibTeXString)
+        bibtexItems = [BDSKBibTeXParser itemsFromString:bibTeXString owner:nil 
error:&error];
+    
+    if ([bibtexItems count] && [error 
isLocalErrorWithCode:kBDSKBibTeXParserFailed] == NO) {
+        BibItem *bibtexItem = [bibtexItems objectAtIndex:0];
+
+        // Get the fulltext URL:
+        [bibtexItem setField:BDSKUrlString toValue:[download contextInfo]];
         
-        NSArray *bibtexItems = [BDSKBibTeXParser itemsFromString:bibTeXString 
owner:nil error:&error];
-        
-        if ([bibtexItems count] && [error 
isLocalErrorWithCode:kBDSKBibTeXParserFailed] == NO) {
-            BibItem *bibtexItem = [bibtexItems objectAtIndex:0];
-
-            // Get the fulltext URL:
-            [bibtexItem setField:BDSKUrlString toValue:[download contextInfo]];
-            
-            items = [NSArray arrayWithObjects:bibtexItem, nil];
-        }
+        items = [NSArray arrayWithObjects:bibtexItem, nil];
+    } else if (outError) {
+        *outError = error;
     }
     
-    [self didFinishDownload:download findingItems:items withSuccess:[items 
count] > 0 error:error];
+    return items;
 }
 
-
-
-
 + (NSDictionary *)parserInfo {
        NSString *parserDescription = NSLocalizedString(@"Alternative interface 
for queries to the PubMed database of medical literature.", @"Description for 
HubMed site");
        return [BDSKWebParser parserInfoWithName:@"HubMed" 
address:@"http://www.hubmed.org/"; description:parserDescription 
feature:BDSKParserFeaturePublic];

Modified: trunk/bibdesk/BDSKIACRParser.m
===================================================================
--- trunk/bibdesk/BDSKIACRParser.m      2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKIACRParser.m      2018-02-23 15:44:34 UTC (rev 22016)
@@ -38,7 +38,6 @@
 
 #import "BDSKIACRParser.h"
 #import "BibItem.h"
-#import "NSError_BDSKExtensions.h"
 #import "NSXMLNode_BDSKExtensions.h"
 #import <AGRegex/AGRegex.h>
 
@@ -62,11 +61,10 @@
        
 }
 
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
 
-    NSMutableArray *items = [NSMutableArray arrayWithCapacity:0];
+    NSMutableArray *items = [NSMutableArray array];
        
-       NSError *error = nil;
     NSURL *url = [self URL];
 
        // is this a search results page or an individual article?
@@ -76,7 +74,7 @@
        NSArray *sources = nil;
     NSXMLElement *rootElement = [[self xmlDocument] rootElement];
     if (isSearch)
-        sources = [rootElement nodesForXPath:@"./body//dt" error:&error];
+        sources = [rootElement nodesForXPath:@"./body//dt" error:outError];
     else
         sources = [NSArray arrayWithObjects:rootElement, nil];
        
@@ -129,7 +127,7 @@
                        
        }
        
-    [self didFinishStartingFindingItems:items withSuccess:YES error:nil];
+    return items;
 }
        
 + (NSDictionary *)parserInfo {

Modified: trunk/bibdesk/BDSKIEEEXploreParser.m
===================================================================
--- trunk/bibdesk/BDSKIEEEXploreParser.m        2018-02-23 07:30:46 UTC (rev 
22015)
+++ trunk/bibdesk/BDSKIEEEXploreParser.m        2018-02-23 15:44:34 UTC (rev 
22016)
@@ -63,7 +63,7 @@
     return [[[xmlDocument rootElement] 
nodesForXPath:containsAbstractPlusLinkNode error:NULL] count] > 0;
 }
 
-- (BOOL)enqueueAbstractPageDownloadForURL:(NSURL *)url error:(NSError 
**)outError
+- (void)enqueueAbstractPageDownloadForURL:(NSURL *)url error:(NSError 
**)outError
 {
     AGRegex *ARNumberRegex = [AGRegex regexWithPattern:@"arnumber=([0-9]+)" 
options:AGRegexMultiline];
     AGRegexMatch *match = [ARNumberRegex findInString:[url query]];
@@ -71,7 +71,6 @@
     if (match == nil) {
         if (outError)
             *outError = [NSError localErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"missingARNumberKey", @"Can't get an 
ARNumber from the URL")];
-        return NO;
     } else {
         NSString *arnumberString = [match groupAtIndex:1];
 
@@ -92,11 +91,10 @@
         NSString *arnumberURLString = [NSString 
stringWithFormat:@"%@://%@/stamp/stamp.jsp?tp=&arnumber=%@", serverScheme, 
serverName, arnumberString];
         
         [self addDownloadWithRequest:request contextInfo:arnumberURLString];
-        return YES;
     }
 }
 
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
 
     /*
     
@@ -110,139 +108,113 @@
      
      */
     
-    NSError *error = nil;    
-    NSMutableArray *items = [NSMutableArray arrayWithCapacity:0];
+    NSError *error = nil;
     NSURL *url = [self URL];
-    BOOL success = NO;
     
     if ([[url path] isCaseInsensitiveEqual:abstractPageURLPath] == NO && [[url 
path] isCaseInsensitiveEqual:searchResultPageURLPath] == NO) {
         
         // parse all links on a TOC page
-        NSArray *abstractPlusLinkNodes = [[[self xmlDocument] rootElement] 
nodesForXPath:containsAbstractPlusLinkNode error:&error];
+        NSArray *abstractPlusLinkNodes = [[[self xmlDocument] rootElement] 
nodesForXPath:containsAbstractPlusLinkNode error:outError];
                
-        if ([abstractPlusLinkNodes count] == 0) {
-            error = [NSError localErrorWithCode:kBDSKUnknownError 
localizedDescription:NSLocalizedString(@"Unable to find links", @"")];
-        } else {
-            for (NSXMLNode *aplinknode in abstractPlusLinkNodes) {
-                NSString *hrefValue = [aplinknode 
stringValueOfAttribute:@"href"];
-                NSURL *abstractPageURL = [NSURL URLWithString:[NSString 
stringWithFormat:@"%@://%@%@", [url scheme], [url host], hrefValue]];
-                
-                if ([self enqueueAbstractPageDownloadForURL:abstractPageURL 
error:&error])
-                    success = YES;
-            }
+        for (NSXMLNode *aplinknode in abstractPlusLinkNodes) {
+            NSString *hrefValue = [aplinknode stringValueOfAttribute:@"href"];
+            NSURL *abstractPageURL = [NSURL URLWithString:[NSString 
stringWithFormat:@"%@://%@%@", [url scheme], [url host], hrefValue]];
+            
+            [self enqueueAbstractPageDownloadForURL:abstractPageURL 
error:&error];
         }
        }
     else {
 
         // already on the abstract page
-        if ([self enqueueAbstractPageDownloadForURL:url error:&error])
-            success = YES;
+        [self enqueueAbstractPageDownloadForURL:url error:&error];
     }
     
-    [self didFinishStartingFindingItems:nil withSuccess:success error:error];
+    return nil;
 }
 
-- (void)downloadDidFinish:(BDSKCitationDownload *)download {
+- (NSArray *)itemsFromDownload:(BDSKCitationDownload *)download error:(NSError 
**)outError {
     BibItem *newPub = nil;
-    NSError *error = [download error];
+    NSError *error = nil;
     NSString *bibTeXString = nil;
     
-    if ([download failed] == NO) {
-        
-        /*
-         Use NSAttributedString to unescape XML entities
-         For example: 
http://ieeexplore.ieee.org/xpls/abs_all.jsp?isnumber=4977283&arnumber=4977305&count=206&index=11
-         has a (tm) as an entity.
+    /*
+     Use NSAttributedString to unescape XML entities
+     For example: 
http://ieeexplore.ieee.org/xpls/abs_all.jsp?isnumber=4977283&arnumber=4977305&count=206&index=11
+     has a (tm) as an entity.
 
-         
http://ieeexplore.ieee.org/search/srchabstract.jsp?arnumber=259629&isnumber=6559&punumber=16&k2dockey=259629@ieeejrns&query=%28%28moll%29%3Cin%3Emetadata%29&pos=1&access=no
-         has smart quotes and a Greek letter (converted) and <sub> and <sup> 
(which are lost).
-         Using stringByConvertingHTMLToTeX will screw up too much stuff here, 
so that's not really an option.
-         */
-        
-        NSAttributedString *attrString = [[[NSAttributedString alloc] 
initWithHTML:[download data] options:[NSDictionary dictionary] 
documentAttributes:NULL] autorelease];
-        bibTeXString = [[attrString string] 
stringByCollapsingAndTrimmingCharactersInSet:[NSCharacterSet 
whitespaceCharacterSet]];
-        
-        /*
-         You'd think the IEEE would be able to produce valid BibTeX, but lots 
of entries have
-         crap like "month=jun 1--aug 1" (unquoted).  They can also end a line 
with a double
-         comma (visible in the downloaded BibTeX, so not my fault).  Either of 
these causes
-         btparse to choke.
-         
-         Unfortunately, BibTeX itself processes these without warnings, so 
there's not much
-         point in complaining to IEEE.  BibTeX just uses the first simple 
value and ignores
-         the rest.
-         */
-        NSScanner *scanner = [[NSScanner alloc] initWithString:bibTeXString];
-        [scanner setCaseSensitive:NO];
-        NSString *scanResult;
-        if ([scanner scanUpToString:@"month=" intoString:&scanResult]) {
-            [scanner scanString:@"month=" intoString:NULL];
-            NSMutableString *fixed = [[scanResult mutableCopy] autorelease];
-            if ([scanner scanUpToString:@"," intoString:&scanResult]) {
-                [fixed appendFormat:@"month={%@},", scanResult];
-                [scanner scanString:@"," intoString:NULL];
-                
-                // basically want to look for spaces and dashes between 
fragments; this is a heuristic, not a strict macro charset
-                static NSCharacterSet *badSet = nil;
-                if (nil == badSet) {
-                    NSMutableCharacterSet *cset = [NSMutableCharacterSet 
characterSetWithRange:NSMakeRange('a', 26)];
-                    [cset addCharactersInRange:NSMakeRange('A', 26)];
-                    [cset addCharactersInString:@"0123456789"];
-                    badSet = [[cset invertedSet] copy];
-                }
-                // unbraced non-letter
-                if ([scanResult rangeOfCharacterFromSet:badSet].length) {
-                    [fixed appendString:[[scanner string] 
substringFromIndex:[scanner scanLocation]]];
-                    bibTeXString = fixed;
-                }
+     
http://ieeexplore.ieee.org/search/srchabstract.jsp?arnumber=259629&isnumber=6559&punumber=16&k2dockey=259629@ieeejrns&query=%28%28moll%29%3Cin%3Emetadata%29&pos=1&access=no
+     has smart quotes and a Greek letter (converted) and <sub> and <sup> 
(which are lost).
+     Using stringByConvertingHTMLToTeX will screw up too much stuff here, so 
that's not really an option.
+     */
+    
+    NSAttributedString *attrString = [[[NSAttributedString alloc] 
initWithHTML:[download data] options:[NSDictionary dictionary] 
documentAttributes:NULL] autorelease];
+    bibTeXString = [[attrString string] 
stringByCollapsingAndTrimmingCharactersInSet:[NSCharacterSet 
whitespaceCharacterSet]];
+    
+    /*
+     You'd think the IEEE would be able to produce valid BibTeX, but lots of 
entries have
+     crap like "month=jun 1--aug 1" (unquoted).  They can also end a line with 
a double
+     comma (visible in the downloaded BibTeX, so not my fault).  Either of 
these causes
+     btparse to choke.
+     
+     Unfortunately, BibTeX itself processes these without warnings, so there's 
not much
+     point in complaining to IEEE.  BibTeX just uses the first simple value 
and ignores
+     the rest.
+     */
+    NSScanner *scanner = [[NSScanner alloc] initWithString:bibTeXString];
+    [scanner setCaseSensitive:NO];
+    NSString *scanResult;
+    if ([scanner scanUpToString:@"month=" intoString:&scanResult]) {
+        [scanner scanString:@"month=" intoString:NULL];
+        NSMutableString *fixed = [[scanResult mutableCopy] autorelease];
+        if ([scanner scanUpToString:@"," intoString:&scanResult]) {
+            [fixed appendFormat:@"month={%@},", scanResult];
+            [scanner scanString:@"," intoString:NULL];
+            
+            // basically want to look for spaces and dashes between fragments; 
this is a heuristic, not a strict macro charset
+            static NSCharacterSet *badSet = nil;
+            if (nil == badSet) {
+                NSMutableCharacterSet *cset = [NSMutableCharacterSet 
characterSetWithRange:NSMakeRange('a', 26)];
+                [cset addCharactersInRange:NSMakeRange('A', 26)];
+                [cset addCharactersInString:@"0123456789"];
+                badSet = [[cset invertedSet] copy];
             }
-            else if ([scanner scanString:@"," intoString:NULL]) {
-                // empty month, unbraced, which also causes btparse to complain
+            // unbraced non-letter
+            if ([scanResult rangeOfCharacterFromSet:badSet].length) {
                 [fixed appendString:[[scanner string] 
substringFromIndex:[scanner scanLocation]]];
                 bibTeXString = fixed;
             }
-            
-            // find and remove ",,\n"
-            NSRange doubleCommaRange = [fixed rangeOfString:@",," 
options:NSLiteralSearch];
-            while (doubleCommaRange.length) {
-                NSUInteger newlineIndex = NSMaxRange(doubleCommaRange) + 1;
-                if (doubleCommaRange.length && newlineIndex < [fixed length] 
&& [[NSCharacterSet newlineCharacterSet] characterIsMember:[fixed 
characterAtIndex:newlineIndex]]) {
-                    [fixed replaceCharactersInRange:doubleCommaRange 
withString:@","];
-                    newlineIndex -= 1;
-                }
-                doubleCommaRange = [fixed rangeOfString:@",," 
options:NSLiteralSearch range:NSMakeRange(newlineIndex, [fixed length] - 
newlineIndex)];
+        }
+        else if ([scanner scanString:@"," intoString:NULL]) {
+            // empty month, unbraced, which also causes btparse to complain
+            [fixed appendString:[[scanner string] substringFromIndex:[scanner 
scanLocation]]];
+            bibTeXString = fixed;
+        }
+        
+        // find and remove ",,\n"
+        NSRange doubleCommaRange = [fixed rangeOfString:@",," 
options:NSLiteralSearch];
+        while (doubleCommaRange.length) {
+            NSUInteger newlineIndex = NSMaxRange(doubleCommaRange) + 1;
+            if (doubleCommaRange.length && newlineIndex < [fixed length] && 
[[NSCharacterSet newlineCharacterSet] characterIsMember:[fixed 
characterAtIndex:newlineIndex]]) {
+                [fixed replaceCharactersInRange:doubleCommaRange 
withString:@","];
+                newlineIndex -= 1;
             }
+            doubleCommaRange = [fixed rangeOfString:@",," 
options:NSLiteralSearch range:NSMakeRange(newlineIndex, [fixed length] - 
newlineIndex)];
         }
-        [scanner release];
-        
-        NSArray *newPubs = nil;
-        if ([NSString isEmptyString:bibTeXString] == NO)
-            newPubs = [BDSKBibTeXParser itemsFromString:bibTeXString owner:nil 
error: &error];
-        else
-            error = [NSError mutableLocalErrorWithCode:kBDSKUnknownError 
localizedDescription:NSLocalizedString(@"No data returned from server", @"")];
-        
-        newPub = [newPubs firstObject];
-        
-        if ([NSString isEmptyString:[newPub valueOfField:BDSKUrlString 
inherit:NO]] && [download contextInfo])
-            [newPub setField:BDSKUrlString toValue:[download contextInfo]];
-        
     }
+    [scanner release];
     
-    if (newPub == nil) {
-        NSString *errMsg = [[download error] localizedDescription];
-        if (nil == errMsg)
-            errMsg = NSLocalizedString(@"Download from IEEEXplore failed.", 
@"error message");
-        NSMutableDictionary *pubFields = [NSMutableDictionary 
dictionaryWithObjectsAndKeys:errMsg, BDSKTitleString, nil];
-        if ([download URL])
-            [pubFields setObject:[[download URL] absoluteString] 
forKey:BDSKUrlString];
-        if ([error localizedRecoverySuggestion])
-            [pubFields setObject:[error localizedRecoverySuggestion] 
forKey:BDSKAbstractString];
-        if (bibTeXString)
-            [pubFields setObject:bibTeXString forKey:BDSKAnnoteString];
-        newPub = [[[BibItem alloc] initWithType:BDSKMiscString citeKey:nil 
pubFields:pubFields isNew:YES] autorelease];
-    }
+    NSArray *newPubs = nil;
+    if ([NSString isEmptyString:bibTeXString] == NO)
+        newPubs = [BDSKBibTeXParser itemsFromString:bibTeXString owner:nil 
error:&error];
+    else
+        error = [NSError mutableLocalErrorWithCode:kBDSKUnknownError 
localizedDescription:NSLocalizedString(@"No data returned from server", @"")];
     
-    [self didFinishDownload:download findingItems:[NSArray 
arrayWithObjects:newPub, nil] withSuccess:YES error:nil];
+    newPub = [newPubs firstObject];
+    
+    if ([NSString isEmptyString:[newPub valueOfField:BDSKUrlString 
inherit:NO]] && [download contextInfo])
+        [newPub setField:BDSKUrlString toValue:[download contextInfo]];
+    
+    return [NSArray arrayWithObjects:newPub, nil];
 }
 
 + (NSDictionary *)parserInfo {

Modified: trunk/bibdesk/BDSKInspireParser.m
===================================================================
--- trunk/bibdesk/BDSKInspireParser.m   2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKInspireParser.m   2018-02-23 15:44:34 UTC (rev 22016)
@@ -74,13 +74,13 @@
     return nodeCount > 0;
 }
 
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
     if ([[[[self URL] path] lowercaseString] hasPrefix:@"/record/"]) {
         NSError *error = nil;
         NSMutableArray *items = [NSMutableArray array];
         NSString *bibtexString = nil;
         
-        NSArray *preNodes = [[[self xmlDocument] rootElement] 
nodesForXPath:@"./body/div/div/pre[contains(text(),'@')]" error:&error];
+        NSArray *preNodes = [[[self xmlDocument] rootElement] 
nodesForXPath:@"./body/div/div/pre[contains(text(),'@')]" error:outError];
         bibtexString = [[[[preNodes firstObject] stringValue] retain] 
autorelease];
         
         NSArray *bibtexItems = nil;
@@ -90,10 +90,13 @@
         if ([bibtexItems count] && [error 
isLocalErrorWithCode:kBDSKBibTeXParserFailed] == NO) {
             BibItem *bibtexItem = [bibtexItems objectAtIndex:0];
             [items addObject:bibtexItem];
+        } else if (outError) {
+            *outError = error;
         }
         
-        [self didFinishStartingFindingItems:items withSuccess:[bibtexItems 
count] > 0 error:error];
-        return;
+        return items;
+    } else {
+        return [super itemsReturningError:outError];
     }
     
     [super start];

Modified: trunk/bibdesk/BDSKJSTORWebParser.m
===================================================================
--- trunk/bibdesk/BDSKJSTORWebParser.m  2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKJSTORWebParser.m  2018-02-23 15:44:34 UTC (rev 22016)
@@ -39,7 +39,6 @@
 #import "BDSKJSTORWebParser.h"
 #import "BDSKBibTeXParser.h"
 #import "BibItem.h"
-#import "NSError_BDSKExtensions.h"
 #import "NSXMLNode_BDSKExtensions.h"
 #import <AGRegex/AGRegex.h>
 
@@ -59,11 +58,8 @@
        
 }
 
-- (void)start {
-
-    NSMutableArray *items = [NSMutableArray arrayWithCapacity:1];
+- (NSArray *)itemsReturningError:(NSError **)outError {
     
-       NSError *error = nil;
        NSStringEncoding encoding = NSASCIIStringEncoding;
        
        // extract JSTOR article number
@@ -70,10 +66,7 @@
        AGRegex *jstorRegex = [AGRegex regexWithPattern:@"^/stable/([0-9]+)"];
        AGRegexMatch *jstorMatch = [jstorRegex findInString:[[self URL] path]];
        
-    if ([jstorMatch count] != 2) {
-        error = [NSError mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
-        [error setValue:NSLocalizedString(@"Unable to parse this page.  Please 
report this to BibDesk's developers and provide the URL.", @"Web parser error") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-    } else {
+    if ([jstorMatch count] == 2) {
         
         NSString *jstorNumber = [jstorMatch groupAtIndex:1];
         NSURL *url = [self URL];
@@ -86,32 +79,25 @@
         [self addDownloadWithRequest:request contextInfo:nil];
     }
     
-    [self didFinishStartingFindingItems:nil withSuccess:error != nil 
error:error];
+    return nil;
 }
 
-- (void)downloadDidFinish:(BDSKCitationDownload *)download  {
-    NSError *error = [download error];
+- (NSArray *)itemsFromDownload:(BDSKCitationDownload *)download error:(NSError 
**)outError  {
     NSArray *bibtexItems = nil;
+    NSString *bibtexString = [download string];
 
-    if ([download failed]) {
-        NSString *bibtexData = [download string];
-        
+    if (bibtexString) {
         // remove characters before the first @ symbol
-        NSRange range = [bibtexData rangeOfString:@"@"];
+        NSRange range = [bibtexString rangeOfString:@"@"];
         if (range.location != NSNotFound) {
-            bibtexData = [bibtexData substringFromIndex:range.location];
+            bibtexString = [bibtexString substringFromIndex:range.location];
             // parse BibTeX data
-            if ([BDSKBibTeXParser canParseString:bibtexData])
-                bibtexItems = [BDSKBibTeXParser itemsFromString:bibtexData 
owner:nil error:&error];
+            if ([BDSKBibTeXParser canParseString:bibtexString])
+                bibtexItems = [BDSKBibTeXParser itemsFromString:bibtexString 
owner:nil error:outError];
         }
     }
     
-    if ([bibtexItems count] == 0 && error == nil) {
-        error = [NSError mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
-        [error setValue:NSLocalizedString(@"Unable to parse this page.  Please 
report this to BibDesk's developers and provide the URL.", @"Web parser error") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-    }
-    
-    [self didFinishDownload:download findingItems:bibtexItems 
withSuccess:[bibtexItems count] > 0 error:error];
+    return bibtexItems;
 }
 
 + (NSDictionary *)parserInfo {

Modified: trunk/bibdesk/BDSKLinkedBibTeXParser.m
===================================================================
--- trunk/bibdesk/BDSKLinkedBibTeXParser.m      2018-02-23 07:30:46 UTC (rev 
22015)
+++ trunk/bibdesk/BDSKLinkedBibTeXParser.m      2018-02-23 15:44:34 UTC (rev 
22016)
@@ -67,19 +67,13 @@
     return nodeCount > 0;
 }
 
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
     
     NSString *bibtexNodePath = [[self class] linkedBibTeXNodeXPath];
     NSError *error = nil;
-    NSArray *bibtexNodes = [[[self xmlDocument] rootElement] 
nodesForXPath:bibtexNodePath error:&error];
+    NSArray *bibtexNodes = [[[self xmlDocument] rootElement] 
nodesForXPath:bibtexNodePath error:outError];
     NSArray *items = nil;
     
-    // return an error when we XPath failed or we found no nodes
-    if ([bibtexNodes count] == 0 && error == nil) {
-        error = [NSError mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
-        [error setValue:NSLocalizedString(@"Unable to parse this page.  Please 
report this to BibDesk's developers and provide the URL.", @"Web parser error") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-    }
-    
     for (NSXMLNode *bibtexNode in bibtexNodes) {
         NSURL *bibtexURL = nil;
         NSString *bibtexURLString = [[self class] 
linkedBibTeXURLStringFromNode:bibtexNode];
@@ -103,10 +97,10 @@
         }
     }
     
-    [self didFinishStartingFindingItems:items withSuccess:[bibtexNodes count] 
!= 0 error:error];
+    return items;
 }
 
-- (void)downloadDidFinish:(BDSKCitationDownload *)download {
+- (NSArray *)itemsFromDownload:(BDSKCitationDownload *)download error:(NSError 
**)outError {
     NSMutableArray *items = [NSMutableArray array];
     NSError *error = nil;
     NSArray *bibtexItems = nil;
@@ -121,24 +115,12 @@
         BibItem *bibtexItem = [bibtexItems objectAtIndex:0];
         [[self class] postProcessItem:bibtexItem];
         [items addObject:bibtexItem];
-    } else {
-        // display a fake item in the table so the user knows one of the items 
failed to parse, but still gets the rest of the data
-        NSString *errMsg = [[download error] localizedDescription];
-        if (errMsg == nil)
-            errMsg = NSLocalizedString(@"Unable to parse as BibTeX", @"Web 
parser error");
-        NSMutableDictionary *pubFields = [NSMutableDictionary 
dictionaryWithObjectsAndKeys:errMsg, BDSKTitleString, nil];
-        if ([download URL])
-            [pubFields setObject:[[download URL] absoluteString] 
forKey:BDSKUrlString];
-        if ([error localizedRecoverySuggestion])
-            [pubFields setObject:[error localizedRecoverySuggestion] 
forKey:BDSKAbstractString];
-        if (bibtexString)
-            [pubFields setObject:bibtexString forKey:BDSKAnnoteString];
-        BibItem *errorItem = [[BibItem alloc] initWithType:BDSKMiscString 
citeKey:nil pubFields:pubFields isNew:YES];
-        [items addObject:errorItem];
-        [errorItem release];
     }
     
-    [self didFinishDownload:download findingItems:items withSuccess:YES 
error:nil];
+    if ([items count] == 0 && outError)
+        *outError = error;
+    
+    return items;
 }
 
 + (NSDictionary *)parserInfo {

Modified: trunk/bibdesk/BDSKMASParser.m
===================================================================
--- trunk/bibdesk/BDSKMASParser.m       2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKMASParser.m       2018-02-23 15:44:34 UTC (rev 22016)
@@ -41,7 +41,6 @@
 #import "BibItem.h"
 #import "NSString_BDSKExtensions.h"
 #import "NSXMLNode_BDSKExtensions.h"
-#import "NSError_BDSKExtensions.h"
 #import <AGRegex/AGRegex.h>
 
 
@@ -63,23 +62,17 @@
     return [nodes count] > 0;
 }
 
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
 
-       NSError *error = nil;
-    
-    NSArray *nodes = [xmlDocument 
nodesForXPath:@"./body//a[starts-with(@href,'../../UserInput/EditPublication?id=')]"
 error:&error];
+    NSArray *nodes = [xmlDocument 
nodesForXPath:@"./body//a[starts-with(@href,'../../UserInput/EditPublication?id=')]"
 error:outError];
     NSString *pattern = 
@"^\\.\\./\\.\\./UserInput/EditPublication\\?id\\=([0-9]*)$";
     
     if ([nodes count] == 0) {
-        nodes = [xmlDocument 
nodesForXPath:@"./body//a[starts-with(@href,'/Publication/')]" error:&error];
+        nodes = [xmlDocument 
nodesForXPath:@"./body//a[starts-with(@href,'/Publication/')]" error:outError];
         pattern = @"^Publication/([0-9]*)/";
         if ([nodes count] == 0) {
-            nodes = [xmlDocument 
nodesForXPath:@"./body//a[starts-with(@href,'/Publication/')]" error:&error];
+            nodes = [xmlDocument 
nodesForXPath:@"./body//a[starts-with(@href,'/Publication/')]" error:outError];
             pattern = @"^/Publication/([0-9]*)/";
-            if ([nodes count] == 0 && error == nil) {
-                error = [NSError 
mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
-                [error setValue:NSLocalizedString(@"Unable to parse this page. 
 Please report this to BibDesk's developers and provide the URL.", @"Web parser 
error") forKey:NSLocalizedRecoverySuggestionErrorKey];
-            }
         }
     }
     
@@ -103,30 +96,19 @@
         [self addDownloadWithRequest:request contextInfo:nil];
     }
     
-    [self didFinishStartingFindingItems:nil withSuccess:error == nil 
error:error];
+    return nil;
 }
 
-- (void)downloadDidFinish:(BDSKCitationDownload *)download  {
-    NSError *error = [download error];
+- (NSArray *)itemsFromDownload:(BDSKCitationDownload *)download error:(NSError 
**)outError {
+    NSError *error = nil;
     NSString *bibtexString = [download string];
     NSArray *bibtexItems = nil;
     NSArray *items = nil;
 
     if (bibtexString)
-        items = [BDSKBibTeXParser itemsFromString:[bibtexString 
stringWithPhoneyCiteKeys:[BibItem defaultCiteKey]] owner:nil error:&error];
+        items = [BDSKBibTeXParser itemsFromString:[bibtexString 
stringWithPhoneyCiteKeys:[BibItem defaultCiteKey]] owner:nil error:outError];
     
-    if ([items count] == 0) {
-        // display a fake item in the table so the user knows one of the items 
failed to parse, but still gets the rest of the data
-        NSString *errMsg = [[download error] localizedDescription];
-        if (errMsg == nil)
-            errMsg = NSLocalizedString(@"Unable to parse as BibTeX", @"Web 
parser error");
-        NSDictionary *pubFields = [NSDictionary 
dictionaryWithObjectsAndKeys:errMsg, BDSKTitleString, [[download URL] 
absoluteString], BDSKUrlString, nil];
-        BibItem *errorItem = [[BibItem alloc] initWithType:BDSKMiscString 
citeKey:nil pubFields:pubFields isNew:YES];
-        items = [NSArray arrayWithObjects:errorItem, nil];
-        [errorItem release];
-    }
-    
-    [self didFinishDownload:download findingItems:items withSuccess:YES 
error:nil];
+    return items;
 }
 
 + (NSDictionary *)parserInfo {

Modified: trunk/bibdesk/BDSKMathSciNetParser.m
===================================================================
--- trunk/bibdesk/BDSKMathSciNetParser.m        2018-02-23 07:30:46 UTC (rev 
22015)
+++ trunk/bibdesk/BDSKMathSciNetParser.m        2018-02-23 15:44:34 UTC (rev 
22016)
@@ -39,7 +39,6 @@
 #import "BDSKMathSciNetParser.h"
 #import "BDSKBibTeXParser.h"
 #import "BibItem.h"
-#import "NSError_BDSKExtensions.h"
 #import <AGRegex/AGRegex.h>
 
 #define MSNBATCHSIZE 50u
@@ -62,20 +61,14 @@
 // Finds strings of type MR1234567 in the current page.
 // Creates a list of their IDs (without leading zeroes), and retrieves the 
BibItems for them.
 // Returns an array with those BibItems.
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
 
-    NSError *error = nil;
-    
        AGRegex * MRRegexp = [AGRegex regexWithPattern:@"MR0*([0-9]+)" 
options:AGRegexMultiline];
        NSArray * regexpResults = [MRRegexp findAllInString:[[self xmlDocument] 
XMLString]];
        
     NSArray * requests = nil;
     
-    if (0 == [regexpResults count]) {// no matches, return an error
-        error = [NSError mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
-        [error setValue:NSLocalizedString(@"Unable to parse this page.  Please 
report this to BibDesk's developers and provide the URL.", @"Web parser error") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-    }
-    else {
+    if ([regexpResults count]) {
         NSMutableArray * IDArray = [NSMutableArray 
arrayWithCapacity:[regexpResults count]];
         
         for (AGRegexMatch * match in regexpResults) {
@@ -85,42 +78,25 @@
             }
         }
         
-        requests = [BDSKMathSciNetParser bibTeXRequestsForMRIDs:IDArray 
referrer:[self URL] error:&error];
+        requests = [BDSKMathSciNetParser bibTeXRequestsForMRIDs:IDArray 
referrer:[self URL] error:outError];
         
         for (NSURLRequest *request in requests)
             [self addDownloadWithRequest:request contextInfo:nil];
     }
     
-    [self didFinishStartingFindingItems:nil withSuccess:[requests count] > 0 
error:error];
+    
+    return nil;
 }
 
-- (void)downloadDidFinish:(BDSKCitationDownload *)download {
+- (NSArray *)itemsFromDownload:(BDSKCitationDownload *)download error:(NSError 
**)outError {
     NSArray *results = nil;
-    NSError *error = [download error];
     NSArray *bibtexItems = nil;
     NSString *bibTeXString = [download string];
     
     if (bibTeXString)
-        results = [BDSKMathSciNetParser bibItemsFromBibTeXString:bibTeXString 
fromURL:[download URL] error:&error];
+        results = [BDSKMathSciNetParser bibItemsFromBibTeXString:bibTeXString 
fromURL:[download URL] error:outError];
     
-    if ([results count] == 0) {
-        // display a fake item in the table so the user knows one of the items 
failed to parse, but still gets the rest of the data
-        NSString *errMsg = [[download error] localizedDescription];
-        if (errMsg == nil)
-            errMsg = NSLocalizedString(@"Unable to parse as BibTeX", @"Web 
parser error");
-        NSMutableDictionary *pubFields = [NSMutableDictionary 
dictionaryWithObjectsAndKeys:errMsg, BDSKTitleString, nil];
-        if ([download URL])
-            [pubFields setObject:[[download URL] absoluteString] 
forKey:BDSKUrlString];
-        if ([error localizedRecoverySuggestion])
-            [pubFields setObject:[error localizedRecoverySuggestion] 
forKey:BDSKAbstractString];
-        if (bibTeXString)
-            [pubFields setObject:bibTeXString forKey:BDSKAnnoteString];
-        BibItem *errorItem = [[BibItem alloc] initWithType:BDSKMiscString 
citeKey:nil pubFields:pubFields isNew:YES];
-        results = [NSArray arrayWithObjects:errorItem, nil];
-        [errorItem release];
-    }
-    
-    [self didFinishDownload:download findingItems:results withSuccess:YES 
error:nil];
+    return results;
 }
 
 // Turns an array of MR ID numbers into an array of NSURLRequest objects to 
download the bibTeX citations.

Modified: trunk/bibdesk/BDSKNumdamParser.m
===================================================================
--- trunk/bibdesk/BDSKNumdamParser.m    2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKNumdamParser.m    2018-02-23 15:44:34 UTC (rev 22016)
@@ -39,9 +39,7 @@
 #import "BDSKNumdamParser.h"
 #import "BDSKMathSciNetParser.h"
 #import "BDSKZentralblattParser.h"
-#import "NSError_BDSKExtensions.h"
 #import "BibItem.h"
-#import "BDSKComplexString.h"
 #import <AGRegex/AGRegex.h>
 
 
@@ -61,11 +59,9 @@
 
 // Find references from Zentralblatt Math referred to by the page. Then look 
them up. Insert link to NUMDAM in the item's own record.
 // (Support for MatSciNet is currently commented out as their lookup script 
requires online-style MR1234567 identifiers and NUMDAM uses paper-style 
identifiers a la 16,957b.)
-- (void)start {
-
-    NSError * error = nil;
+- (NSArray *)itemsReturningError:(NSError **)outError {
     
-    NSArray * tableCells = [[[self xmlDocument] rootElement] 
nodesForXPath:@".//td[@id='contenu']" error:&error];
+    NSArray * tableCells = [[[self xmlDocument] rootElement] 
nodesForXPath:@".//td[@id='contenu']" error:outError];
     NSXMLElement * tableCell = [tableCells objectAtIndex:0];
     NSString * content = [tableCell stringValue];
     
@@ -121,7 +117,7 @@
     }
     
     /*
-     NSArray * MRRequests = [BDSKMathSciNetParser 
bibTeXRequestsForZMathIDs:ZMathReferences referrer:[self URL] error:&error];
+     NSArray * MRRequests = [BDSKMathSciNetParser 
bibTeXRequestsForZMathIDs:ZMathReferences referrer:[self URL] error:outError];
      
      for (NSURLRequest *request in MRRequests) {
      NSDictionary *contextInfo = [NSDictionary 
dictionaryWithObjectsAndKeys:[BDSKMathSciNetParser class], @"parserClass", 
firstMRIDIsOwnId ? content : nil, @"content", nil];
@@ -130,7 +126,7 @@
      }
      */
     
-    NSArray * ZMathRequests = [BDSKZentralblattParser 
bibTeXRequestsForZMathIDs:ZMathReferences referrer:[self URL] error:&error];
+    NSArray * ZMathRequests = [BDSKZentralblattParser 
bibTeXRequestsForZMathIDs:ZMathReferences referrer:[self URL] error:outError];
     
     for (NSURLRequest *request in ZMathRequests) {
         NSDictionary *contextInfo = [NSDictionary 
dictionaryWithObjectsAndKeys:[BDSKZentralblattParser class], @"parserClass", 
firstZMathIDIsOwnId ? content : nil, @"content", nil];
@@ -138,13 +134,11 @@
         firstZMathIDIsOwnId = NO;
     }
     
-    BOOL success = /* [MRRequests count] > 0 && */ [ZMathRequests count] > 0;
-    [self didFinishStartingFindingItems:nil withSuccess:success error:error];
+    return nil;
 }
 
-- (void)downloadDidFinish:(BDSKCitationDownload *)download {
+- (NSArray *)itemsFromDownload:(BDSKCitationDownload *)download error:(NSError 
**)outError {
     NSArray *results = nil;
-    NSError *error = [download error];
     NSArray *bibtexItems = nil;
     NSString *bibTeXString = [download string];
     NSDictionary *contextInfo = [download contextInfo];
@@ -152,24 +146,9 @@
     NSString *content = [contextInfo objectForKey:@"content"];
     
     if (bibTeXString)
-        results = [parserClass bibItemsFromBibTeXString:bibTeXString 
fromURL:[download URL] error:&error];
+        results = [parserClass bibItemsFromBibTeXString:bibTeXString 
fromURL:[download URL] error:outError];
     
-    if ([results count] == 0) {
-        // display a fake item in the table so the user knows one of the items 
failed to parse, but still gets the rest of the data
-        NSString *errMsg = [[download error] localizedDescription];
-        if (errMsg == nil)
-            errMsg = NSLocalizedString(@"Unable to parse as BibTeX", @"Web 
parser error");
-        NSMutableDictionary *pubFields = [NSMutableDictionary 
dictionaryWithObjectsAndKeys:errMsg, BDSKTitleString, nil];
-        if ([download URL])
-            [pubFields setObject:[[download URL] absoluteString] 
forKey:BDSKUrlString];
-        if ([error localizedRecoverySuggestion])
-            [pubFields setObject:[error localizedRecoverySuggestion] 
forKey:BDSKAbstractString];
-        if (bibTeXString)
-            [pubFields setObject:bibTeXString forKey:BDSKAnnoteString];
-        BibItem *errorItem = [[BibItem alloc] initWithType:BDSKMiscString 
citeKey:nil pubFields:pubFields isNew:YES];
-        results = [NSArray arrayWithObjects:errorItem, nil];
-        [errorItem release];
-    } else if (content) {
+    if ([results count] > 0 && content != nil) {
         // add Numdam URL to item's own record
         BibItem *item = [results objectAtIndex:0];
         if ( [item isKindOfClass:[BibItem class]] ) {
@@ -189,7 +168,7 @@
         }
     }
     
-    [self didFinishDownload:download findingItems:results withSuccess:YES 
error:nil];
+    return results;
 }
 
 + (NSDictionary *)parserInfo {

Modified: trunk/bibdesk/BDSKProjectEuclidParser.m
===================================================================
--- trunk/bibdesk/BDSKProjectEuclidParser.m     2018-02-23 07:30:46 UTC (rev 
22015)
+++ trunk/bibdesk/BDSKProjectEuclidParser.m     2018-02-23 15:44:34 UTC (rev 
22016)
@@ -39,9 +39,7 @@
 #import "BDSKProjectEuclidParser.h"
 #import "BDSKMathSciNetParser.h"
 #import "BDSKZentralblattParser.h"
-#import "NSError_BDSKExtensions.h"
 #import "BibItem.h"
-#import "BDSKComplexString.h"
 #import <AGRegex/AGRegex.h>
 
 
@@ -60,24 +58,15 @@
 }
 
 // Find references for Mathematical Reviews and Zentralblatt Math in the page. 
Then look them up, giving preference to MSN if both are available.
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
 
-       NSError * error;
-    
-       NSArray * identifiers = [[[self xmlDocument] rootElement] 
nodesForXPath:@".//div[@id='identifier']/p" error:&error];
+       NSArray * identifiers = [[[self xmlDocument] rootElement] 
nodesForXPath:@".//div[@id='identifier']/p" error:outError];
        
     NSArray *MRRequests = nil;
     NSArray *ZMathRequests = nil;
 
-    if ( [identifiers count] == 0 ) {// no matches, return an error
+    if ( [identifiers count] ) {
         
-        if (error == nil) {
-            error = [NSError mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
-            [error setValue:NSLocalizedString(@"Unable to parse this page.  
Please report this to BibDesk's developers and provide the URL.", @"Web parser 
error") forKey:NSLocalizedRecoverySuggestionErrorKey];
-        }
-        
-    } else {
-        
         NSXMLElement * identifier = [identifiers objectAtIndex:0];
         NSString * identifierString = [identifier stringValue];
         
@@ -97,7 +86,7 @@
         }
         
         // Set up arrays for the lists of MathSciNet and Zentralblatt IDs. 
These will have the ID for the current element at position 0 and contain NSNull 
when no ID is found for the respective service.
-        NSArray * references = [[[self xmlDocument] rootElement] 
nodesForXPath:@".//div[@id='references']/div[@class='ref-block']" error:&error];
+        NSArray * references = [[[self xmlDocument] rootElement] 
nodesForXPath:@".//div[@id='references']/div[@class='ref-block']" 
error:outError];
         NSMutableArray * MRIDs = [NSMutableArray arrayWithObjects:myMRID, nil];
         NSMutableArray * ZMathIDs = [NSMutableArray 
arrayWithObjects:myZMathID, nil];
         
@@ -116,7 +105,7 @@
             }
         }
         
-        MRRequests = [BDSKMathSciNetParser bibTeXRequestsForMRIDs:MRIDs 
referrer:[self URL] error:&error];
+        MRRequests = [BDSKMathSciNetParser bibTeXRequestsForMRIDs:MRIDs 
referrer:[self URL] error:outError];
         
         NSString *myIdentifier = myMRID ? identifierString : nil;
         for (NSURLRequest *request in MRRequests) {
@@ -125,7 +114,7 @@
             myIdentifier = nil;
         }
         
-        ZMathRequests = [BDSKZentralblattParser 
bibTeXRequestsForZMathIDs:ZMathIDs referrer:[self URL] error:&error];
+        ZMathRequests = [BDSKZentralblattParser 
bibTeXRequestsForZMathIDs:ZMathIDs referrer:[self URL] error:outError];
         
         myIdentifier = myZMathID ? identifierString : nil;
         for (NSURLRequest *request in ZMathRequests) {
@@ -135,13 +124,13 @@
         }
     }
     
-    BOOL success = [MRRequests count] > 0 || [ZMathRequests count] > 0;
-    [self didFinishStartingFindingItems:nil withSuccess:success error:error];
+    
+    return nil;
 }
 
-- (void)downloadDidFinish:(BDSKCitationDownload *)download {
+- (NSArray *)itemsFromDownload:(BDSKCitationDownload *)download error:(NSError 
**)outError {
     NSArray *results = nil;
-    NSError *error = [download error];
+    NSError *error = nil;
     NSArray *bibtexItems = nil;
     NSString *bibTeXString = [download string];
     NSDictionary *contextInfo = [download contextInfo];
@@ -152,22 +141,7 @@
         // parse the bibTeX string with the correct parser
         results = [parserClass bibItemsFromBibTeXString:bibTeXString 
fromURL:[download URL] error:&error];
     
-    if ([results count] == 0) {
-        // display a fake item in the table so the user knows one of the items 
failed to parse, but still gets the rest of the data
-        NSString *errMsg = [[download error] localizedDescription];
-        if (errMsg == nil)
-            errMsg = NSLocalizedString(@"Unable to parse as BibTeX", @"Web 
parser error");
-        NSMutableDictionary *pubFields = [NSMutableDictionary 
dictionaryWithObjectsAndKeys:errMsg, BDSKTitleString, nil];
-        if ([download URL])
-            [pubFields setObject:[[download URL] absoluteString] 
forKey:BDSKUrlString];
-        if ([error localizedRecoverySuggestion])
-            [pubFields setObject:[error localizedRecoverySuggestion] 
forKey:BDSKAbstractString];
-        if (bibTeXString)
-            [pubFields setObject:bibTeXString forKey:BDSKAnnoteString];
-        BibItem *errorItem = [[BibItem alloc] initWithType:BDSKMiscString 
citeKey:nil pubFields:pubFields isNew:YES];
-        results = [NSArray arrayWithObjects:errorItem, nil];
-        [errorItem release];
-    } else if (myIdentifier) {
+    if ([results count] > 0 && myIdentifier != nil) {
         // add Project Euclid URL to item's own record
         NSObject * item = [results objectAtIndex:0];
         if ( [item isKindOfClass:[BibItem class]] ) {
@@ -186,7 +160,7 @@
         }
     }
     
-    [self didFinishDownload:download findingItems:results withSuccess:YES 
error:nil];
+    return results;
 }
 
 

Modified: trunk/bibdesk/BDSKWebParser.h
===================================================================
--- trunk/bibdesk/BDSKWebParser.h       2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKWebParser.h       2018-02-23 15:44:34 UTC (rev 22016)
@@ -55,6 +55,7 @@
     NSXMLDocument *xmlDocument;
     NSURL *URL;
     id<BDSKWebParserDelegate> delegate;
+    BOOL finishedStarting;
 }
 
 // this method is the main entry point for the BDSKWebParser class
@@ -74,11 +75,13 @@
 @property (nonatomic, readonly) DOMDocument *domDocument;
 @property (nonatomic, readonly) NSXMLDocument *xmlDocument;
 @property (nonatomic, readonly) NSURL *URL;
+
 @property (nonatomic, assign) id<BDSKWebParserDelegate> delegate;
 
-// these two methods should be implemented by subclasses
-+ (BOOL)canParseDocument:(DOMDocument *)domDocument xmlDocument:(NSXMLDocument 
*)xmlDocument fromURL:(NSURL *)url;
-+ (NSDictionary *)parserInfo;
+// set at the end of -start, to know thereis not more coming, so we may finish
+@property (nonatomic) BOOL finishedStarting;
+// whether the parser can finish, e.g. no pending additions or downloads
+@property (nonatomic, readonly) BOOL canFinish;
 
 - (id)initWithDocument:(DOMDocument *)aDomDocument xmlDocument:(NSXMLDocument 
*)aXmlDocument fromURL:(NSURL *)aURL;
 
@@ -85,10 +88,15 @@
 - (void)start;
 - (void)cancel;
 
-// convenience method to call the various delegate methods if needed
-// subclasses can use this at the end of sartWithDelegate: instead of calling 
the delegate methods
-- (void)didFinishStartingFindingItems:(NSArray *)items 
withSuccess:(BOOL)success error:(NSError *)error;
+// whether the parsershould finish with success, can be overridden by 
subclasses returning items async
+- (BOOL)succeededWithItems:(NSArray *)items;
 
+// the next three methods should be implemented by subclasses
++ (BOOL)canParseDocument:(DOMDocument *)domDocument xmlDocument:(NSXMLDocument 
*)xmlDocument fromURL:(NSURL *)url;
++ (NSDictionary *)parserInfo;
+
+- (NSArray *)itemsReturningError:(NSError **)outError;
+
 @end
 
 @protocol BDSKWebParserDelegate <NSObject>

Modified: trunk/bibdesk/BDSKWebParser.m
===================================================================
--- trunk/bibdesk/BDSKWebParser.m       2018-02-23 07:30:46 UTC (rev 22015)
+++ trunk/bibdesk/BDSKWebParser.m       2018-02-23 15:44:34 UTC (rev 22016)
@@ -57,6 +57,7 @@
 #import "BDSKCOinSParser.h"
 #import "BDSKIEEEXploreParser.h"
 #import "BDSKMASParser.h"
+#import "BibItem.h"
 #import "NSError_BDSKExtensions.h"
 #import "BDSKRuntime.h"
 
@@ -67,7 +68,8 @@
 
 @implementation BDSKWebParser
 
-@synthesize domDocument, xmlDocument, URL, delegate;
+@synthesize domDocument, xmlDocument, URL, delegate, finishedStarting;
+@dynamic canFinish;
 
 + (NSArray *)webParserClasses {
     static NSArray *webParsers = nil;
@@ -206,18 +208,41 @@
     [super dealloc];
 }
 
-- (void)start {}
+- (void)start {
+    NSError *error = nil;
+    
+    NSArray *items = [self itemsReturningError:&error];
+    
+    BOOL success = [self succeededWithItems:items];
+    
+    if (success == NO && error == nil) {
+        error = [NSError mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
+        [error setValue:NSLocalizedString(@"Unable to parse this page.  Please 
report this to BibDesk's developers and provide the URL.", @"Web parser error") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
+    }
+    
+    if ([items count] > 0)
+        [[self delegate] webParser:self didFindItems:items];
+    
+    [self setFinishedStarting:YES];
+    
+    if ([self canFinish])
+        [[self delegate] webParser:self didFinishWithSuccess:success 
error:error];
+}
 
 - (void)cancel {
     [self setDelegate:nil];
 }
 
-- (void)didFinishStartingFindingItems:(NSArray *)items 
withSuccess:(BOOL)success error:(NSError *)error {
-    if ([items count] > 0)
-        [[self delegate] webParser:self didFindItems:items];
-    [[self delegate] webParser:self didFinishWithSuccess:success error:error];
+- (BOOL)canFinish {
+    return [self finishedStarting];
 }
 
+- (BOOL)succeededWithItems:(NSArray *)items {
+    return [items count] > 0;
+}
+
+- (NSArray *)itemsReturningError:(NSError **)outError { return nil; }
+
 + (BOOL)canParseDocument:(DOMDocument *)domDocument xmlDocument:(NSXMLDocument 
*)xmlDocument fromURL:(NSURL *)url { return NO; }
 
 + (NSDictionary *)parserInfo { return nil; }

Modified: trunk/bibdesk/BDSKZentralblattParser.m
===================================================================
--- trunk/bibdesk/BDSKZentralblattParser.m      2018-02-23 07:30:46 UTC (rev 
22015)
+++ trunk/bibdesk/BDSKZentralblattParser.m      2018-02-23 15:44:34 UTC (rev 
22016)
@@ -39,7 +39,6 @@
 #import "BDSKZentralblattParser.h"
 #import "BDSKBibTeXParser.h"
 #import "BibItem.h"
-#import "NSError_BDSKExtensions.h"
 #import <AGRegex/AGRegex.h>
 
 #define ZMATHBATCHSIZE 100u
@@ -62,7 +61,7 @@
 // Find occurrences of strings Zbl [pre]1234.56789 or JFM 12.3456.78 on the 
page.
 // Extract their IDs and look them up.
 // Return the resulting BibItems.
-- (void)start {
+- (NSArray *)itemsReturningError:(NSError **)outError {
 
     NSError *error = nil;
     
@@ -71,11 +70,7 @@
        
     NSArray * requests = nil;
     
-    if (0 == [regexpResults count]) {// no matches, return an error
-        error = [NSError mutableLocalErrorWithCode:kBDSKWebParserFailed 
localizedDescription:NSLocalizedString(@"No search results found", @"Web parser 
error")];
-        [error setValue:NSLocalizedString(@"Unable to parse this page.  Please 
report this to BibDesk's developers and provide the URL.", @"Web parser error") 
forKey:NSLocalizedRecoverySuggestionErrorKey];
-    }
-    else {
+    if ([regexpResults count]) {
         NSMutableArray * IDArray = [NSMutableArray 
arrayWithCapacity:[regexpResults count]];
         
         for (AGRegexMatch *match in regexpResults) {
@@ -85,42 +80,23 @@
             }
         }
         
-        requests = [BDSKZentralblattParser bibTeXRequestsForZMathIDs:IDArray 
referrer:[self URL] error:&error];
+        requests = [BDSKZentralblattParser bibTeXRequestsForZMathIDs:IDArray 
referrer:[self URL] error:outError];
         
         for (NSURLRequest *request in requests)
             [self addDownloadWithRequest:request contextInfo:nil];
     }
     
-    [self didFinishStartingFindingItems:nil withSuccess:[requests count] > 0 
error:error];
+    return nil;
 }
 
-- (void)downloadDidFinish:(BDSKCitationDownload *)download {
+- (NSArray *)itemsFromDownload:(BDSKCitationDownload *)download error:(NSError 
**)outError {
     NSArray *results = nil;
-    NSError *error = nil;
-    NSArray *bibtexItems = nil;
     NSString *bibTeXString = [download string];
     
     if (bibTeXString)
-        results = [BDSKZentralblattParser 
bibItemsFromBibTeXString:bibTeXString fromURL:[download URL] error:&error];
+        results = [BDSKZentralblattParser 
bibItemsFromBibTeXString:bibTeXString fromURL:[download URL] error:outError];
     
-    if ([results count] == 0) {
-        // display a fake item in the table so the user knows one of the items 
failed to parse, but still gets the rest of the data
-        NSString *errMsg = [[download error] localizedDescription];
-        if (errMsg == nil)
-            errMsg = NSLocalizedString(@"Unable to parse as BibTeX", @"Web 
parser error");
-        NSMutableDictionary *pubFields = [NSMutableDictionary 
dictionaryWithObjectsAndKeys:errMsg, BDSKTitleString, nil];
-        if ([download URL])
-            [pubFields setObject:[[download URL] absoluteString] 
forKey:BDSKUrlString];
-        if ([error localizedRecoverySuggestion])
-            [pubFields setObject:[error localizedRecoverySuggestion] 
forKey:BDSKAbstractString];
-        if (bibTeXString)
-            [pubFields setObject:bibTeXString forKey:BDSKAnnoteString];
-        BibItem *errorItem = [[BibItem alloc] initWithType:BDSKMiscString 
citeKey:nil pubFields:pubFields isNew:YES];
-        results = [NSArray arrayWithObjects:errorItem, nil];
-        [errorItem release];
-    }
-    
-[self didFinishDownload:download findingItems:results withSuccess:YES 
error:nil];
+    return results;
 }
 
 // Turns an array of Zentralblatt Math IDs into an array of NSURLRequest 
objects for bibtex data.

Modified: trunk/bibdesk/English.lproj/Localizable.strings
===================================================================
(Binary files differ)

Modified: trunk/bibdesk/French.lproj/Localizable.strings
===================================================================
(Binary files differ)

Modified: trunk/bibdesk/German.lproj/Localizable.strings
===================================================================
(Binary files differ)

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Bibdesk-commit mailing list
Bibdesk-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to