From 214bc814ea620473d84ec61790dbea41264a93c7 Mon Sep 17 00:00:00 2001 From: Jonathan Mitchell Date: Mon, 16 Feb 2015 21:35:10 +0000 Subject: [PATCH] Implemented number formatting --- PDFPageBuilder.xcodeproj/project.pbxproj | 8 ++++ PDFPageBuilder/TSPageBuilder.m | 6 ++- PDFPageBuilder/TSPageNumberFormatter.h | 20 ++++++++ PDFPageBuilder/TSPageNumberFormatter.m | 61 ++++++++++++++++++++++++ PageBuilderDemo/Demo-A4.map.xml | 10 ++-- 5 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 PDFPageBuilder/TSPageNumberFormatter.h create mode 100644 PDFPageBuilder/TSPageNumberFormatter.m diff --git a/PDFPageBuilder.xcodeproj/project.pbxproj b/PDFPageBuilder.xcodeproj/project.pbxproj index 74aea92..0662398 100644 --- a/PDFPageBuilder.xcodeproj/project.pbxproj +++ b/PDFPageBuilder.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + AB22FF461A928B8900D971EA /* TSPageNumberFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = AB22FF441A928B8900D971EA /* TSPageNumberFormatter.h */; }; + AB22FF471A928B8900D971EA /* TSPageNumberFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = AB22FF451A928B8900D971EA /* TSPageNumberFormatter.m */; }; ABD2518F1A4994DD00BB4BFC /* PDFPageBuilder.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABD251831A4994DD00BB4BFC /* PDFPageBuilder.framework */; }; ABD251961A4994DD00BB4BFC /* PDFPageBuilderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = ABD251951A4994DD00BB4BFC /* PDFPageBuilderTests.m */; }; ABD251DB1A49969C00BB4BFC /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABD251DA1A49969C00BB4BFC /* Cocoa.framework */; }; @@ -85,6 +87,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + AB22FF441A928B8900D971EA /* TSPageNumberFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSPageNumberFormatter.h; sourceTree = ""; }; + AB22FF451A928B8900D971EA /* TSPageNumberFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSPageNumberFormatter.m; sourceTree = ""; }; ABD251831A4994DD00BB4BFC /* PDFPageBuilder.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PDFPageBuilder.framework; sourceTree = BUILT_PRODUCTS_DIR; }; ABD2518E1A4994DD00BB4BFC /* PDFPageBuilderTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PDFPageBuilderTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; ABD251941A4994DD00BB4BFC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = ../PDFPageBuilderTests/Info.plist; sourceTree = ""; }; @@ -280,6 +284,8 @@ ABF40C111A49B8D30070368E /* TSPDFPage.h */, ABF40C121A49B8D30070368E /* TSPDFPage.m */, ABF40C321A49B8FA0070368E /* PDFPageBuilder.h */, + AB22FF441A928B8900D971EA /* TSPageNumberFormatter.h */, + AB22FF451A928B8900D971EA /* TSPageNumberFormatter.m */, ); path = PDFPageBuilder; sourceTree = ""; @@ -321,6 +327,7 @@ ABF40C151A49B8D30070368E /* NSColor+PageBuilder.h in Headers */, ABF40C221A49B8D30070368E /* TSPageBuilder.h in Headers */, ABF40C241A49B8D30070368E /* TSPageDoubleAggregator.h in Headers */, + AB22FF461A928B8900D971EA /* TSPageNumberFormatter.h in Headers */, ABF40C1F1A49B8D30070368E /* NSXMLElement+PageBuilder.h in Headers */, ABF40C1B1A49B8D30070368E /* NSRegularExpression+PageBuilder.h in Headers */, ABF40C171A49B8D30070368E /* NSDate+PageBuilder.h in Headers */, @@ -495,6 +502,7 @@ ABF40C1C1A49B8D30070368E /* NSRegularExpression+PageBuilder.m in Sources */, ABF40C2D1A49B8D30070368E /* TSPageTextItem.m in Sources */, ABF40C251A49B8D30070368E /* TSPageDoubleAggregator.m in Sources */, + AB22FF471A928B8900D971EA /* TSPageNumberFormatter.m in Sources */, ABF40C1A1A49B8D30070368E /* NSMutableArray+PageBuilder.m in Sources */, ABF40C141A49B8D30070368E /* NSAttributedString+PageBuilder.m in Sources */, ABF40C271A49B8D30070368E /* TSPageImageItem.m in Sources */, diff --git a/PDFPageBuilder/TSPageBuilder.m b/PDFPageBuilder/TSPageBuilder.m index 784d33c..1e933ce 100644 --- a/PDFPageBuilder/TSPageBuilder.m +++ b/PDFPageBuilder/TSPageBuilder.m @@ -34,6 +34,7 @@ #import "TSPageBuilder.h" #import "TSPageDoubleAggregator.h" #import "TSPageSpacingAggregator.h" +#import "TSPageNumberFormatter.h" // categories #import "NSString+PageBuilder.h" @@ -823,10 +824,11 @@ - (NSString *)replaceKeysInString:(NSString *)text fromObject:(id)object stringValue = @""; - } else if ([value isKindOfClass:[NSDecimalNumber class]]) { + } else if ([value isKindOfClass:[NSNumber class]]) { // use the valueFormat - stringValue = [value description]; + TSPageNumberFormatter *formatter = [[TSPageNumberFormatter alloc] initWithWPFStyleFormatString:valueFormat]; + stringValue = [formatter stringFromNumber:value]; } else if ([value isKindOfClass:[NSDate class]]) { diff --git a/PDFPageBuilder/TSPageNumberFormatter.h b/PDFPageBuilder/TSPageNumberFormatter.h new file mode 100644 index 0000000..fe9af89 --- /dev/null +++ b/PDFPageBuilder/TSPageNumberFormatter.h @@ -0,0 +1,20 @@ +// +// TSPageNumberFormatter.h +// PDFPageBuilder +// +// Created by Jonathan Mitchell on 16/02/2015. +// Copyright (c) 2015 Thesaurus Software. All rights reserved. +// + +#import + +@interface TSPageNumberFormatter : NSNumberFormatter + +/*! + + Initialise with WPF style formatter as per https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx + + */ +- (id)initWithWPFStyleFormatString:(NSString *)wpfStyleFormatter; + +@end diff --git a/PDFPageBuilder/TSPageNumberFormatter.m b/PDFPageBuilder/TSPageNumberFormatter.m new file mode 100644 index 0000000..461cba6 --- /dev/null +++ b/PDFPageBuilder/TSPageNumberFormatter.m @@ -0,0 +1,61 @@ +// +// TSPageNumberFormatter.m +// PDFPageBuilder +// +// Created by Jonathan Mitchell on 16/02/2015. +// Copyright (c) 2015 Thesaurus Software. All rights reserved. +// + +#import "TSPageNumberFormatter.h" + +@implementation TSPageNumberFormatter + +#pragma mark - +#pragma mark Lifecycle + +- (id)initWithWPFStyleFormatString:(NSString *)wpfStyleFormatter +{ + self = [super init]; + + // see https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx + NSString *formatSpecifier = [[wpfStyleFormatter substringWithRange:NSMakeRange(0, 1)] uppercaseString]; + NSInteger precisionSpecifier = 0; + if (wpfStyleFormatter.length > 1) { + precisionSpecifier = [[wpfStyleFormatter substringWithRange:NSMakeRange(1, wpfStyleFormatter.length - 1)] integerValue]; + } + + // numeric + if ([formatSpecifier isEqualToString:@"N"] || [formatSpecifier isEqualToString:@"F"]) { + + self.numberStyle = NSNumberFormatterDecimalStyle; + [self setHasThousandSeparators:YES]; + + // scientific + } else if ([formatSpecifier isEqualToString:@"E"]) { + + self.numberStyle = kCFNumberFormatterScientificStyle; + + // percent + } else if ([formatSpecifier isEqualToString:@"P"]) { + + self.numberStyle = kCFNumberFormatterPercentStyle; + + // currency + } else if ([formatSpecifier isEqualToString:@"C"]) { + + self.numberStyle = NSNumberFormatterCurrencyStyle; + [self setHasThousandSeparators:YES]; + + } else { + + // other document WPF format specifiers can be implemented as required + self.numberStyle = NSNumberFormatterNoStyle; + } + + [self setMaximumFractionDigits:precisionSpecifier]; + [self setMinimumFractionDigits:precisionSpecifier]; + + return self; +} + +@end diff --git a/PageBuilderDemo/Demo-A4.map.xml b/PageBuilderDemo/Demo-A4.map.xml index 8f64357..3cf587c 100644 --- a/PageBuilderDemo/Demo-A4.map.xml +++ b/PageBuilderDemo/Demo-A4.map.xml @@ -46,25 +46,25 @@ {Key} - {Value} + {Value} {Key} - £{Value:N02} + £{Value:N2} {Key} - £{Value:N02} + £{Value:N3} Total - £{Box2Total:N02} + £{Box2Total:N2} Total - £{Box3Total:N02} + £{Box3Total:N3}