Skip to content

Commit

Permalink
Initial commit of code extracted from my super-secret iPhone project
Browse files Browse the repository at this point in the history
  • Loading branch information
tomafro committed May 28, 2009
0 parents commit ad2c51d
Show file tree
Hide file tree
Showing 5 changed files with 490 additions and 0 deletions.
29 changes: 29 additions & 0 deletions ActiveSupportInflector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Inflector.h
// TrollyDolly
//
// Created by Tom Ward on 26/05/2009.
// Copyright 2009 Tom Ward. All rights reserved.
//

#import <Foundation/Foundation.h>


@interface ActiveSupportInflector : NSObject {
NSMutableSet* uncountableWords;
NSMutableArray* pluralRules;
NSMutableArray* singularRules;
}

- (void)addInflectionsFromFile:(NSString*)path;
- (void)addInflectionsFromDictionary:(NSDictionary*)dictionary;

- (void)addUncountableWord:(NSString*)string;
- (void)addIrregularRuleForSingular:(NSString*)singular plural:(NSString*)plural;
- (void)addPluralRuleFor:(NSString*)rule replacement:(NSString*)replacement;
- (void)addSingularRuleFor:(NSString*)rule replacement:(NSString*)replacement;

- (NSString*)pluralize:(NSString*)string;
- (NSString*)singularize:(NSString*)string;

@end
130 changes: 130 additions & 0 deletions ActiveSupportInflector.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
//
// Inflector.m
// TrollyDolly
//
// Created by Tom Ward on 26/05/2009.
// Copyright 2009 Tom Ward. All rights reserved.
//

#import "ActiveSupportInflector.h"
#import "RegexKitLite.h"

@interface ActiveSupportInflectorRule : NSObject
{
NSString* rule;
NSString* replacement;
}

@property (retain) NSString* rule;
@property (retain) NSString* replacement;

+ (ActiveSupportInflectorRule*) rule:(NSString*)rule replacement:(NSString*)replacement;

@end

@implementation ActiveSupportInflectorRule
@synthesize rule;
@synthesize replacement;

+ (ActiveSupportInflectorRule*) rule:(NSString*)rule replacement:(NSString*)replacement {
ActiveSupportInflectorRule* result;
if (result = [[[super init] alloc] autorelease]) {
[result setRule:rule];
[result setReplacement:replacement];
}
return result;
}

@end


@interface ActiveSupportInflector(PrivateMethods)
- (NSString*)_applyInflectorRules:(NSArray*)rules toString:(NSString*)string;
@end

@implementation ActiveSupportInflector

- (ActiveSupportInflector*)init {
if (self = [super init]) {
uncountableWords = [[NSMutableSet alloc] init];
pluralRules = [[NSMutableArray alloc] init];
singularRules = [[NSMutableArray alloc] init];
[self addInflectionsFromFile:[[NSBundle bundleForClass:[self class]] pathForResource:@"ActiveSupportInflector" ofType:@"plist"]];
}
return self;
}

- (void)addInflectionsFromFile:(NSString*)path {
[self addInflectionsFromDictionary:[NSDictionary dictionaryWithContentsOfFile:path]];
}

- (void)addInflectionsFromDictionary:(NSDictionary*)dictionary {
for (NSArray* pluralRule in [dictionary objectForKey:@"pluralRules"]) {
[self addPluralRuleFor:[pluralRule objectAtIndex:0] replacement:[pluralRule objectAtIndex:1]];
}

for (NSArray* singularRule in [dictionary objectForKey:@"singularRules"]) {
[self addSingularRuleFor:[singularRule objectAtIndex:0] replacement:[singularRule objectAtIndex:1]];
}

for (NSArray* irregularRule in [dictionary objectForKey:@"irregularRules"]) {
[self addIrregularRuleForSingular:[irregularRule objectAtIndex:0] plural:[irregularRule objectAtIndex:1]];
}

for (NSString* uncountableWord in [dictionary objectForKey:@"uncountableWords"]) {
[self addUncountableWord:uncountableWord];
}
}

- (void)addUncountableWord:(NSString*)string {
[uncountableWords addObject:string];
}

- (void)addIrregularRuleForSingular:(NSString*)singular plural:(NSString*)plural {
NSString* singularRule = [NSString stringWithFormat:@"%@$", plural];
[self addSingularRuleFor:singularRule replacement:singular];

NSString* pluralRule = [NSString stringWithFormat:@"%@$", singular];
[self addPluralRuleFor:pluralRule replacement:plural];
}

- (void)addPluralRuleFor:(NSString*)rule replacement:(NSString*)replacement {
[pluralRules insertObject:[ActiveSupportInflectorRule rule:rule replacement: replacement] atIndex:0];
}

- (void)addSingularRuleFor:(NSString*)rule replacement:(NSString*)replacement {
[singularRules insertObject:[ActiveSupportInflectorRule rule:rule replacement: replacement] atIndex:0];
}

- (NSString*)pluralize:(NSString*)singular {
return [self _applyInflectorRules:pluralRules toString:singular];
}

- (NSString*)singularize:(NSString*)plural {
return [self _applyInflectorRules:singularRules toString:plural];
}

- (NSString*)_applyInflectorRules:(NSArray*)rules toString:(NSString*)string {
if ([uncountableWords containsObject:string]) {
return string;
}
else {
for (ActiveSupportInflectorRule* rule in rules) {
if ([string isMatchedByRegex:[rule rule]]) {
NSLog([rule rule]);
NSLog([rule replacement]);
return [string stringByReplacingOccurrencesOfRegex:[rule rule] withString:[rule replacement]];
}
}
return string;
}
}

- (void)dealloc {
[super dealloc];
[uncountableWords release];
[pluralRules release];
[singularRules release];
}

@end
206 changes: 206 additions & 0 deletions ActiveSupportInflector.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
{
pluralRules = (
(
"$",
s,
),
(
"s$",
s,
),
(
"(ax|test)is$",
"$1es",
),
(
"(octop|vir)us$",
"$1i",
),
(
"(alias|status)$",
"$1es",
),
(
"(bu)s$",
"$1ses",
),
(
"(buffal|tomat)o$",
"$1oes",
),
(
"([ti])um$",
"$1a",
),
(
"sis$",
ses,
),
(
"(?:([^f])fe|([lr])f)$",
"$1$2ves",
),
(
"(hive)$",
"$1s",
),
(
"([^aeiouy]|qu)y$",
"$1ies",
),
(
"(x|ch|ss|sh)$",
"$1es",
),
(
"(matr|vert|ind)ix|ex$",
"$1ices",
),
(
"([m|l])ouse$",
"$1ice",
),
(
"^(ox)$",
"$1en",
),
(
"(quiz)$",
"$1zes",
),
);
singularRules = (
(
"(.)s$",
"$1",
),
(
"(n)ews$",
"$1ews",
),
(
"([ti])a$",
"$1um",
),
(
"(analy|ba|diagno|parenthe|progno|synop|the)ses$",
"$1sis",
),
(
"(^analy)ses$",
"$1sis",
),
(
"([^f])ves$",
"$1fe",
),
(
"(hive)s$",
"$1",
),
(
"(tive)s$",
"$1",
),
(
"([lr])ves$",
"$1f",
),
(
"([^aeiouy]|qu)ies$",
"$1y",
),
(
"series$",
"series",
),
(
"movies$",
"movie",
),
(
"(x|ch|ss|sh)es$",
"$1",
),
(
"([m|l])ice$",
"$1ouse",
),
(
"(bus)es$",
"$1",
),
(
"(o)es$",
"$1",
),
(
"(shoe)s$",
"$1",
),
(
"(cris|ax|test)es$",
"$1is",
),
(
"(octop|vir)i$",
"$1us",
),
(
"(alias|status)es$",
"$1",
),
(
"^(ox)en",
"$1",
),
(
"(vert|ind)ices$",
"$1ex",
),
(
"(matr)ices$",
"$1ix",
),
(
"(quiz)zes$",
"$1",
),
);
irregularRules = (
(
person,
people,
),
(
man,
men,
),
(
child,
children,
),
(
sex,
sexes,
),
(
move,
moves,
),
(
database,
databases
)
);
uncountableWords = (
equipment,
information,
rice,
money,
species,
series,
fish,
sheep,
);
}
Loading

0 comments on commit ad2c51d

Please sign in to comment.