Permalink
Browse files

Improve paragraph wrapping

  • Loading branch information...
1 parent fe254ea commit bce378ceefe021f04f1de3507724d550180fea50 @jjgod committed Jul 13, 2012
Showing with 88 additions and 6 deletions.
  1. +1 −1 Info.plist
  2. +3 −0 TTDocument.h
  3. +78 −1 TTDocument.mm
  4. +6 −4 TTTextView.mm
View
@@ -44,7 +44,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>2.3</string>
+ <string>2.3.1</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
View
@@ -15,6 +15,7 @@
NSMutableAttributedString *fileContents;
NSString *fileContentsInPlainText;
NSUInteger lastReadLocation;
+ NSCharacterSet *linePrefixCharset;
}
@property (retain) NSMutableAttributedString *fileContents;
@@ -23,5 +24,7 @@
- (NSDictionary *) attributesForText;
- (void) saveMetaData;
+- (NSString *) firstLine: (NSString *) line;
+- (void) outputTo: (NSMutableString *) output from: (NSString *) contents;
@end
View
@@ -56,6 +56,7 @@ - (id) init
fileContents = nil;
lastReadLocation = 0;
+ linePrefixCharset = [NSCharacterSet characterSetWithCharactersInString: @"  "];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *keyPaths = [NSArray arrayWithObjects: @"backgroundColor", @"lineHeight", @"fontName", @"fontSize", nil];
@@ -132,6 +133,79 @@ - (NSDictionary *) attributesForText
return attributes;
}
+#define outputLine(output, line) [output appendFormat: @"%@\n", line]
+#define outputParagraph(output, paragraph) do { \
+[output appendFormat: @"%@\n\n", paragraph]; \
+[paragraph release]; \
+paragraph = nil; \
+} while (0)
+
+- (NSString *) firstLine: (NSString *) line
+{
+ line = [line stringByTrimmingCharactersInSet: linePrefixCharset];
+
+ // Align first line with “「 optically
+ NSString *prefix = @"  ";
+ if (line.length > 0) {
+ UniChar ch = [line characterAtIndex: 0];
+ if (ch == 0x201C /**/ || ch == 0x300C /**/)
+ prefix = @" ";
+ }
+
+ return [prefix stringByAppendingString: line];
+}
+
+- (void) outputTo: (NSMutableString *) output from: (NSString *) contents
+{
+ BOOL inParagraph = NO;
+ NSUInteger length = [contents length];
+ NSUInteger start = 0, end = 0;
+ NSRange range, lineRange;
+ NSString *line;
+ NSMutableString *paragraph = nil;
+ NSCharacterSet *newlineCharset = [NSCharacterSet newlineCharacterSet];
+
+ for (range = NSMakeRange(0, 0); end < length; range.location = end)
+ {
+ [contents getLineStart: &start
+ end: &end
+ contentsEnd: NULL
+ forRange: range];
+ lineRange = NSMakeRange(start, end - start);
+ line = [[contents substringWithRange: lineRange] stringByTrimmingCharactersInSet: newlineCharset];
+ if (inParagraph)
+ {
+ if ([line length] == 0) {
+ inParagraph = NO;
+ outputParagraph(output, paragraph);
+ }
+ else if ([line hasPrefix: @""] || [line hasPrefix: @"*"] || [line hasPrefix: @""]) {
+ inParagraph = NO;
+ outputParagraph(output, paragraph);
+ outputLine(output, line);
+ }
+ else if ([line hasPrefix: @" "] || [line hasPrefix: @" "]) {
+ outputParagraph(output, paragraph);
+ paragraph = [[NSMutableString alloc] initWithString: [self firstLine: line]];
+ }
+ else
+ [paragraph appendString: line];
+ } else {
+ if ([line hasPrefix: @" "] || [line hasPrefix: @" "])
+ {
+ inParagraph = YES;
+ paragraph = [[NSMutableString alloc] initWithString: [self firstLine: line]];
+ } else {
+ outputLine(output, line);
+ }
+ }
+ }
+
+ if (inParagraph && paragraph && [paragraph length]) {
+ outputParagraph(output, paragraph);
+ }
+}
+
- (BOOL) readFromURL: (NSURL *) absoluteURL
ofType: (NSString *) typeName
error: (NSError **) outError
@@ -147,8 +221,11 @@ - (BOOL) readFromURL: (NSURL *) absoluteURL
if (fileContents)
[fileContents release];
- [self setFileContentsInPlainText: [contents stringByReplacingOccurrencesOfString: @"\r"
+ NSMutableString *wrappedText = [[NSMutableString alloc] init];
+ [self outputTo: wrappedText from: [contents stringByReplacingOccurrencesOfString: @"\r"
withString: @""]];
+ [self setFileContentsInPlainText: wrappedText];
+ [wrappedText release];
// Remove DOS line endings
fileContents = [[NSMutableAttributedString alloc] initWithString: self.fileContentsInPlainText
attributes: [self attributesForText]];
View
@@ -93,12 +93,14 @@ - (void) invalidateLayout
if (width <= maxWidth - fontSize) {
if (secondCharInNextLineIndex < text.length) {
UniChar ch = CFStringGetCharacterAtIndex(str, secondCharInNextLineIndex);
+ // TODO: handle ⋯⋯” at the beginning of next line
if ((ch == 0xFF0C /**/ || ch == 0x3002 /**/ ||
ch == 0x3001 /**/ || ch == 0xFF01 /**/ ||
ch == 0xFF1A /**/ || ch == 0xFF1B /**/ ||
- ch == 0x201D /**/)) {
+ ch == 0x201D /**/) || ch == 0x201C /**/ ||
+ ch == 0x300C /**/ || ch == 0xFF1F /**/) {
CFRelease(lineData.line);
- length += 2;
+ length += (ch == 0x201C || ch == 0x300C) ? 1 : 2;
// For situations like ",”" or "。」", we need to extend the length one more char
// to include the quote
@@ -114,8 +116,8 @@ - (void) invalidateLayout
if (start + length < text.length && CFStringGetCharacterAtIndex(str, start + length) == '\n')
length += 1;
} else {
- // Otherwise we can't do optical punctuation, do justified line instead
- if (width / maxWidth > 0.85) {
+ // Otherwise we can't do optical punctuation or the beginning of a paragraph, do justified line instead
+ if (width / maxWidth > 0.85 && CFStringGetCharacterAtIndex(str, start) != 0x3000) {
CTLineRef justifiedLine = CTLineCreateJustifiedLine(lineData.line, 1.0, maxWidth);
CFRelease(lineData.line);
lineData.line = justifiedLine;

0 comments on commit bce378c

Please sign in to comment.