Created
July 24, 2018 06:30
-
-
Save fwextensions/2bbdd453bc941dcfa36b06065c760980 to your computer and use it in GitHub Desktop.
Bodged together test of QSSense.m
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Cocoa/Cocoa.h> | |
// | |
// QSense.m | |
// QSqSense | |
// | |
// Created by Alcor on 11/22/04. | |
// Copyright 2004 Blacktree. All rights reserved. | |
// | |
#import "QSSense.h" | |
#define MIN_ABBR_OPTIMIZE 0 | |
#define IGNORED_SCORE 0.9 | |
#define SKIPPED_SCORE 0.15 | |
CGFloat QSScoreForAbbreviationWithRanges(CFStringRef str, CFStringRef abbr, id mask, CFRange strRange, CFRange abbrRange); | |
CGFloat QSScoreForAbbreviation(CFStringRef str, CFStringRef abbr, id mask) { | |
return QSScoreForAbbreviationOrTransliteration(str, abbr, mask); | |
} | |
CGFloat QSScoreForAbbreviationOrTransliteration(CFStringRef str, CFStringRef abbr, id mask) { | |
CGFloat score = QSScoreForAbbreviationWithRanges(str, abbr, mask, CFRangeMake(0, CFStringGetLength(str)), CFRangeMake(0, CFStringGetLength(abbr))); | |
if (score == 0) { | |
CFMutableStringRef mutableString = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, str); | |
CFStringTransform(mutableString, nil, kCFStringTransformToLatin, false); | |
if (CFStringCompare(str, mutableString, 0) != kCFCompareEqualTo) { | |
// only do this if the two strings are not equal (otherwise it's a wasted compute) | |
score = QSScoreForAbbreviationWithRanges(mutableString, abbr, nil, CFRangeMake(0, CFStringGetLength(mutableString)), CFRangeMake(0, CFStringGetLength(abbr))); | |
} | |
if (mutableString) { | |
CFRelease(mutableString); | |
} | |
return score; | |
} | |
return score; | |
} | |
CGFloat QSScoreForAbbreviationWithRanges(CFStringRef str, CFStringRef abbr, id mask, CFRange strRange, CFRange abbrRange) { | |
printf("call: %s\n", CFStringGetCStringPtr(abbr, kCFStringEncodingMacRoman)); | |
if (!abbrRange.length) | |
return IGNORED_SCORE; //deduct some points for all remaining letters | |
if (abbrRange.length > strRange.length) | |
return 0.0; | |
static CFCharacterSetRef wordSeparator = NULL; | |
static CFCharacterSetRef uppercase = NULL; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
wordSeparator = CFCharacterSetCreateMutableCopy(NULL, CFCharacterSetGetPredefined(kCFCharacterSetWhitespace)); | |
CFCharacterSetAddCharactersInString((CFMutableCharacterSetRef)wordSeparator, (CFStringRef)@"."); | |
uppercase = CFCharacterSetGetPredefined(kCFCharacterSetUppercaseLetter); | |
}); | |
// Create an inline buffer version of str. Will be used in loop below | |
// for faster lookups. | |
CFStringInlineBuffer inlineBuffer; | |
CFStringInitInlineBuffer(str, &inlineBuffer, strRange); | |
// this will correctly fill the buffer with the entire string | |
// CFStringInitInlineBuffer(str, &inlineBuffer, CFRangeMake(0, CFStringGetLength(str))); | |
CFLocaleRef userLoc = CFLocaleCopyCurrent(); | |
CGFloat score = 0.0, remainingScore = 0.0; | |
CFIndex i, j; | |
CFRange matchedRange, remainingStrRange, adjustedStrRange = strRange; | |
// Search for steadily smaller portions of the abbreviation | |
for (i = abbrRange.length; i > 0; i--) { | |
CFStringRef curAbbr = CFStringCreateWithSubstring (NULL, abbr, CFRangeMake(abbrRange.location, i) ); | |
// terminality | |
// axeen | |
BOOL found = CFStringFindWithOptionsAndLocale(str, curAbbr, | |
CFRangeMake(adjustedStrRange.location, adjustedStrRange.length - abbrRange.length + i), | |
kCFCompareCaseInsensitive | kCFCompareDiacriticInsensitive | kCFCompareLocalized, | |
userLoc, &matchedRange); | |
printf("%i found: %i\n", (int) i, found); | |
// this prints null when the string gets down to 1 or 2 chars. ffs. | |
// printf("%i %s\n", (int) i, CFStringGetCStringPtr(curAbbr, kCFStringEncodingUTF8)); | |
CFShow(curAbbr); | |
CFRelease(curAbbr); | |
if (!found) { | |
continue; | |
} | |
if (mask) { | |
[mask addIndexesInRange:NSMakeRange(matchedRange.location, matchedRange.length)]; | |
} | |
remainingStrRange.location = matchedRange.location + matchedRange.length; | |
remainingStrRange.length = strRange.location + strRange.length - remainingStrRange.location; | |
// Search what is left of the string with the rest of the abbreviation | |
remainingScore = QSScoreForAbbreviationWithRanges(str, abbr, mask, remainingStrRange, CFRangeMake(abbrRange.location + i, abbrRange.length - i)); | |
if (remainingScore) { | |
score = remainingStrRange.location-strRange.location; | |
// ignore skipped characters if is first letter of a word | |
if (matchedRange.location > strRange.location) { | |
// if some letters were skipped | |
UniChar previousChar = CFStringGetCharacterFromInlineBuffer(&inlineBuffer, matchedRange.location - 1); | |
UniChar character = CFStringGetCharacterFromInlineBuffer(&inlineBuffer, matchedRange.location); | |
printf("prev and current: %c %c (%i %i)\n", previousChar, character, (int) matchedRange.location - 1, (int) matchedRange.location); | |
if (CFCharacterSetIsCharacterMember(wordSeparator, previousChar)) { | |
// We're on the first letter of a word | |
for (j = matchedRange.location - 2; j >= strRange.location; j--) { | |
if (CFCharacterSetIsCharacterMember(wordSeparator, CFStringGetCharacterFromInlineBuffer(&inlineBuffer, j))) | |
score--; | |
else | |
score -= SKIPPED_SCORE; | |
} | |
} else if (CFCharacterSetIsCharacterMember(uppercase, character)) { | |
for (j = matchedRange.location - 1; j >= strRange.location; j--) { | |
if (CFCharacterSetIsCharacterMember(uppercase, CFStringGetCharacterFromInlineBuffer(&inlineBuffer, j))) | |
score--; | |
else | |
score -= SKIPPED_SCORE; | |
} | |
} else { | |
printf("before: %.20f minus %i %f\n", score, (matchedRange.location-strRange.location)/2, (float) (matchedRange.location-strRange.location)/2); | |
score -= (matchedRange.location-strRange.location)/2; | |
printf("after: %.20f\n", score); | |
} | |
} | |
score += remainingScore * remainingStrRange.length; | |
score /= strRange.length; | |
CFRelease(userLoc); | |
printf("score: %.20f\n", score); | |
return score; | |
} | |
} | |
CFRelease(userLoc); | |
return 0; | |
} | |
int main(int argc, const char * argv[]) { | |
CFStringRef str = CFSTR("Test string"); | |
// printf("%.20f\n", QSScoreForAbbreviation(str, CFSTR("t"), nil)); | |
// printf("%.20f\n", QSScoreForAbbreviation(str, CFSTR("ts"), nil)); | |
printf("%.20f\n", QSScoreForAbbreviation(str, CFSTR("tet"), nil)); | |
// printf("%.20f\n", QSScoreForAbbreviation(str, CFSTR("str"), nil)); | |
// printf("%.20f\n", QSScoreForAbbreviation(str, CFSTR("ng"), nil)); | |
printf("%.20f\n", QSScoreForAbbreviation(CFSTR("react hot loader"), CFSTR("rhl"), nil)); | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment