Skip to content

Commit

Permalink
Implemented number formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan Mitchell committed Feb 16, 2015
1 parent e7fab71 commit 214bc81
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 7 deletions.
8 changes: 8 additions & 0 deletions PDFPageBuilder.xcodeproj/project.pbxproj
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -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 = "<group>"; };
AB22FF451A928B8900D971EA /* TSPageNumberFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSPageNumberFormatter.m; sourceTree = "<group>"; };
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 = "<group>"; };
Expand Down Expand Up @@ -280,6 +284,8 @@
ABF40C111A49B8D30070368E /* TSPDFPage.h */,
ABF40C121A49B8D30070368E /* TSPDFPage.m */,
ABF40C321A49B8FA0070368E /* PDFPageBuilder.h */,
AB22FF441A928B8900D971EA /* TSPageNumberFormatter.h */,
AB22FF451A928B8900D971EA /* TSPageNumberFormatter.m */,
);
path = PDFPageBuilder;
sourceTree = "<group>";
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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 */,
Expand Down
6 changes: 4 additions & 2 deletions PDFPageBuilder/TSPageBuilder.m
Expand Up @@ -34,6 +34,7 @@
#import "TSPageBuilder.h"
#import "TSPageDoubleAggregator.h"
#import "TSPageSpacingAggregator.h"
#import "TSPageNumberFormatter.h"

// categories
#import "NSString+PageBuilder.h"
Expand Down Expand Up @@ -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]]) {

Expand Down
20 changes: 20 additions & 0 deletions 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 <Foundation/Foundation.h>

@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
61 changes: 61 additions & 0 deletions 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
10 changes: 5 additions & 5 deletions PageBuilderDemo/Demo-A4.map.xml
Expand Up @@ -46,25 +46,25 @@

<ForEach Enumerable="Box1Details" Text.Y="38.064" Text.YSpacing="0">
<Text X="12" Width="40" Foreground="404142">{Key}</Text>
<Text X="12" Width="57.667" TextAlignment="Right" FontFamily="Arial">{Value}</Text>
<Text X="12" Width="57.667" TextAlignment="Right" FontFamily="Arial">{Value}</Text>
</ForEach>

<ForEach Enumerable="Box2Details" Text.Y="38.064" Text.YSpacing="0">
<Text X="76.167" Width="40" Foreground="404142">{Key}</Text>
<Text X="76.167" Width="57.667" TextAlignment="Right" FontFamily="Arial">£{Value:N02}</Text>
<Text X="76.167" Width="57.667" TextAlignment="Right" FontFamily="Arial">£{Value:N2}</Text>
</ForEach>

<ForEach Enumerable="Box3Details" Text.Y="38.064" Text.YSpacing="0">
<Text X="140.333" Width="40" Foreground="404142">{Key}</Text>
<Text X="140.333" Width="57.667" TextAlignment="Right" FontFamily="Times">£{Value:N02}</Text>
<Text X="140.333" Width="57.667" TextAlignment="Right" FontFamily="Times">£{Value:N3}</Text>
</ForEach>

<Push Property="TextVerticalAlignment" Value="Bottom" />
<Push Property="FontStyle" Value="Italic" />
<Text X="76.167" Y="28.905" Width="57.667" Height="51.167" Foreground="404142">Total</Text>
<Text X="76.167" Y="28.905" Width="57.667" Height="51.167" TextAlignment="Right">£{Box2Total:N02}</Text>
<Text X="76.167" Y="28.905" Width="57.667" Height="51.167" TextAlignment="Right">£{Box2Total:N2}</Text>
<Text X="140.333" Y="28.905" Width="57.667" Height="51.167" Foreground="404142">Total</Text>
<Text X="140.333" Y="28.905" Width="57.667" Height="51.167" TextAlignment="Right">£{Box3Total:N02}</Text>
<Text X="140.333" Y="28.905" Width="57.667" Height="51.167" TextAlignment="Right">£{Box3Total:N3}</Text>
<Pop Property="FontStyle" />
<Pop Property="TextVerticalAlignment" />

Expand Down

0 comments on commit 214bc81

Please sign in to comment.