Git Product home page Git Product logo

bonmot's People

Contributors

acacuce avatar akolov avatar alexrrouse avatar aral avatar canonsawrey avatar chrisballinger avatar devvenusk avatar dostrander avatar ejohansson avatar eliotw1 avatar ethanschatzline avatar imperiopolis avatar jatraiz avatar jdhealy avatar joihelgi avatar jvisenti avatar kingofbrian avatar kviksilver avatar lordisturbia avatar lukeandrews239 avatar muukii avatar nikolayjuly avatar noremac avatar nuudles avatar ohkanghoon avatar rdingman avatar rzulkoski avatar stleamist avatar tettoffensive avatar zeveisenberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bonmot's Issues

Better support for paragraph styles

Paragraph styles are respected only when applied to the first character of a string, or to the first character after a \n in a multi-paragraph string. Are there improvements that can be made in BonMot's handling of paragraph style attributes?

Support changing text case

A BONText should be able to specify that its string will be transformed to uppercase, lowercase, and title case.

Better naming

Right now, you chain BONTextConfiguration objects in BONChainLink wrappers using the RZCursive macro. There are some parts I like, but I would prefer more descriptive names that give some hint as to what each part does. I would also prefer two names (configuration and wrapper), or even one (just configuration), rather than three (configuration, wrapper, and macro)

Support strikethrough text

BonMot should make it easy to strike through part or all of a string. If multiple strikethrough styles are available, those should be supported as well.

Add unit tests for UIKit classes’ KVO-ability

BONTextAlignmentConstraint relies (or heavily implies reliance) on the KVO-ability of the font property of UILabel, UIButton, UITextView, and UITextField. We should add unit tests to check our assumptions about these properties. We should probably also add KVO for titleLabel.font for the case of UIButton.

We should also check whether setting the attributedText of these objects triggers KVO on font, and if not, add observation for attributedText.

Fix negative tracking

if ( trackingInPoints > 0.0f ) {

This line in BONTextConfiguration precludes negative tracking values, which should be supported. This should be changed to trackingInPoints != 0.0f or, to appease the float comparison gods, a custom floatsCloseEnough(trackingInPoints, 0.0f).

Readme with example usage

BonMot should have a ReadMe that illustrates why it is useful, what it can do, how to get started, and where to learn more.

Support using NSKernAttributeName for auto-kerning with UILabel

From the iOS 8.3 UILabel documentation:

To turn on auto-kerning in the label, set NSKernAttributeName of the string to [NSNull null].

To research

  • What exactly does "auto-kerning" mean in this context?
  • Does it have performance implications?
  • Does it work only for UILabel? What about UITextView, UITextField, Core Animation, and Core Graphics?

Unit tests

BonMot should have full test coverage, both of string generation and of ancillary tasks such as custom constraints and image tinting (assuming those are not split out into external projects).

Update BONSpecialGenerator.swift for latest Xcode 7

Xcode 7 beta 5 caused BONSpecialGenerator.swift to fail to compile:

scripts/BONSpecialGenerator.swift:38:51: error: expression does not conform to type 'NilLiteralConvertible'
            CFStringTransform(theCFMutableString, nil, kCFStringTransformToUnicodeName, 0)
                                                  ^~~
scripts/BONSpecialGenerator.swift:63:36: error: 'split(_:maxSplit:allowEmptySlices:isSeparator:)' is unavailable: Use the split() method instead.
        let components: [String] = split(self.characters){$0 == " " || $0 == "-"}.map(String.init)
                                   ^~~~~
Swift.split:1:76: note: 'split(_:maxSplit:allowEmptySlices:isSeparator:)' has been explicitly marked unavailable here
@available(*, unavailable, message="Use the split() method instead.") func split<S : CollectionType, R : BooleanType>(elements: S, maxSplit: Int = default, allowEmptySlices: Bool = default, @noescape isSeparator: (S.Generator.Element) -> R) -> [S.SubSequence]
                                                                           ^
scripts/BONSpecialGenerator.swift:79:27: error: 'stringByDeletingLastPathComponent' is unavailable: Use stringByDeletingLastPathComponent on NSString instead.
        let path = script.stringByDeletingLastPathComponent
                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Foundation.String:299:7: note: 'stringByDeletingLastPathComponent' has been explicitly marked unavailable here
  var stringByDeletingLastPathComponent: String { get }
      ^
scripts/BONSpecialGenerator.swift:87:33: error: 'stringByDeletingLastPathComponent' is unavailable: Use stringByDeletingLastPathComponent on NSString instead.
                let path = path.stringByDeletingLastPathComponent
                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Foundation.String:299:7: note: 'stringByDeletingLastPathComponent' has been explicitly marked unavailable here
  var stringByDeletingLastPathComponent: String { get }
      ^
scripts/BONSpecialGenerator.swift:126:43: error: 'stringByAppendingPathComponent' is unavailable: Use stringByAppendingPathComponent on NSString instead.
let headerTemplatePath = currentDirectory.stringByAppendingPathComponent("BONSpecial.h template.txt")
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Foundation.String:287:8: note: 'stringByAppendingPathComponent' has been explicitly marked unavailable here
  func stringByAppendingPathComponent(aString: String) -> String
       ^
scripts/BONSpecialGenerator.swift:127:51: error: 'stringByAppendingPathComponent' is unavailable: Use stringByAppendingPathComponent on NSString instead.
let implementationTemplatePath = currentDirectory.stringByAppendingPathComponent("BONSpecial.m template.txt")
                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Foundation.String:287:8: note: 'stringByAppendingPathComponent' has been explicitly marked unavailable here
  func stringByAppendingPathComponent(aString: String) -> String
       ^
scripts/BONSpecialGenerator.swift:145:41: error: 'stringByDeletingLastPathComponent' is unavailable: Use stringByDeletingLastPathComponent on NSString instead.
let projectDirectory = currentDirectory.stringByDeletingLastPathComponent
                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Foundation.String:299:7: note: 'stringByDeletingLastPathComponent' has been explicitly marked unavailable here
  var stringByDeletingLastPathComponent: String { get }
      ^
scripts/BONSpecialGenerator.swift:146:41: error: 'stringByAppendingPathComponent' is unavailable: Use stringByAppendingPathComponent on NSString instead.
let classesDirectory = projectDirectory.stringByAppendingPathComponent("Pod/Classes")
                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Foundation.String:287:8: note: 'stringByAppendingPathComponent' has been explicitly marked unavailable here
  func stringByAppendingPathComponent(aString: String) -> String
       ^
scripts/BONSpecialGenerator.swift:149:35: error: 'stringByAppendingPathExtension' is unavailable: Use stringByAppendingPathExtension on NSString instead.
let headerFileName = baseFileName.stringByAppendingPathExtension("h")!
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Foundation.String:291:8: note: 'stringByAppendingPathExtension' has been explicitly marked unavailable here
  func stringByAppendingPathExtension(ext: String) -> String?
       ^
scripts/BONSpecialGenerator.swift:150:43: error: 'stringByAppendingPathExtension' is unavailable: Use stringByAppendingPathExtension on NSString instead.
let implementationFileName = baseFileName.stringByAppendingPathExtension("m")!
                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Foundation.String:291:8: note: 'stringByAppendingPathExtension' has been explicitly marked unavailable here
  func stringByAppendingPathExtension(ext: String) -> String?
       ^
scripts/BONSpecialGenerator.swift:151:39: error: 'stringByAppendingPathComponent' is unavailable: Use stringByAppendingPathComponent on NSString instead.
let headerFilePath = classesDirectory.stringByAppendingPathComponent(headerFileName)
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Foundation.String:287:8: note: 'stringByAppendingPathComponent' has been explicitly marked unavailable here
  func stringByAppendingPathComponent(aString: String) -> String
       ^
scripts/BONSpecialGenerator.swift:152:47: error: 'stringByAppendingPathComponent' is unavailable: Use stringByAppendingPathComponent on NSString instead.
let implementationFilePath = classesDirectory.stringByAppendingPathComponent(implementationFileName)
                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Foundation.String:287:8: note: 'stringByAppendingPathComponent' has been explicitly marked unavailable here
  func stringByAppendingPathComponent(aString: String) -> String
       ^

Make text alignment constraints usable in code

Currently, RZTextAlignmentConstraint works in IB but not in code. When writing programmatic constraints, you should be able to easily create constraints that pin labels' cap height, x-height, or baseline to any vertical attribute of any other view.

Underlining

Don't bother implementing this unless someone specifically requests it for a shipping product, and even then, try to talk them out of it. No one likes underlining except my high school English teachers.

Support superscripts/subscripts

If a font has super/sub character alternates, BonMot should be able to use them. If it does not, BonMot should be able to report this in a run-time log message or exception.

Nice to have: if a font doesn't have proper super/sub alternates, some designers will still accomplish the effect using a heaver weight, smaller size, and baseline shift (all of which are currently supported in BonMot). Can we make this process more streamlined, perhaps with special API for creating super/sub attributes to use when real alternate characters are not available?

Cleaner Concatenation

Using .nextTextConfiguration can be cumbersome, since there is currently not DSL syntax to easily chain text configuration objects together. This should either be streamlined, or it should be removed, and you just use categories on NSArray to join text configuration objects.

Test whether BONTextAlignmentConstraint causes retain cycles

BONTextAlignmentConstraint strongly holds its firstItem and secondItem internally. This causes a known retain cycle if a view referenced by the constraint also strongly holds the constraint. However, there may be unintended retain cycles caused by internal details of the layout system. This should be tested to determine whether it is a problem.

Better printing of special characters

  • Make a function that will pretty-print any string's special characters
  • Option to print inline or one-character-per-line
  • Option to include image addresses or not (for determinism)
  • Make -debugDescription on BONText and BONChain use these methods.
  • Unit tests
  • Optional: add category to NSString to make this more streamlined.

Implement missing attributes in BONTextAlignmentConstraint

case BONConstraintAttributeFirstBaseline: // fall through
case BONConstraintAttributeLastBaseline: // fall through
case BONConstraintAttributeBottom: // fall through
case BONConstraintAttributeUnspecified: {
    [NSException raise:NSInternalInconsistencyException format:@"Not implemented yet"];
    break;
}

More streamlined image tinting

-[UIImage rz_tintedImageWithColor:] exists, but you have to use it first before inserting the image into the string. It should be done automatically if a string with an embedded image also has a textColor set (or maybe use a separate imageColor property).

Nice logo

BotMot should have a nice logo, preferably one that illustrates its capabilities with attributed strings.

Easy way to create a new line

New line characters are part of the line they are on, rather than the line they lead in to. Rather than having to create and append a text configuration with a \n each time you want s new line, there should be a shorthand to append a new line to an existing BONChain.

Full documentation of font parameters

The wiki attached to this project should include detailed examples of what each font property and custom constraint attribute can do, complete with screenshots and usage examples.

Support text alignment

Support NSTextAlignment on strings.

To research:

  • What happens when you apply text alignment to only part of a string?
  • What happens when you apply different text alignments to different parts of the same string? Should this be a runtime exception, or is it supported? Is the behavior defined?
  • As a possible solution, can we apply one paragraph style with text alignment to the whole concatenated string after it is constructed?

Use mutable attributed strings instead of concatenation

In Apple's WWDC 2012 talk that introduces attributed strings on iOS 6, they mention that modifying an attributed string is more efficient than concatenating multiple attributed strings. I would like to write some tests to confirm this, and if it is still true, change BonMot to use mutable attributed strings when building its strings.

Carthage support

I'd like to see carthage support alongside cocoa pods support so that I can use my dependency manager of choice

Small caps

If the font supports native small caps, we should be able to use them. If not, a runtime error should occur - no ugly small caps here!

More advanced example

Example project should have some more advanced examples. @jkaufman suggested something along these lines:

screen shot 2015-07-13 at 10 29 41 pm

I would also like to include thin/hairline/nonbreaking/weird spaces and text attachments

Unit testing helpers

One of the intents of BonMot is to make it easy to write unit tests for the attributed strings that a view model might return. These strings may contain hard-to-distinguish characters such as nonbreaking spaces, which can make it difficult to write unit tests.

BonMot should have a method to transform a string into a human-readable version, like this:

{image attachment}{nonbreaking space}My cool label text{hair space}{image attachment}{nonbreaking space}Another piece of label text

The purpose would be to write a unit testing macro that works like this:

BONAssertEquivalentStrings(someViewModel.someProperty, @"{image attachment}{nonbreaking space}My cool label text{hair space}{image attachment}{nonbreaking space}Another piece of label text");

You would pre-generate the testing string via a utility method in BonMot, and then copy and paste it into your unit test. The BONAssertEquivalentStrings() macro takes two strings, runs the BonMot conversion on the first one, and then XCTAssertEqualObjectses them to see if they contain the same characters.

Bonus points: generate a useful error message that highlights, via a ^ character on the next line, at which index the two strings first differ.

Make it easy to query a font's features

Provide a convenience wrapper around CTFontCopyFeatures() so users can easily see if a font supports a requested feature. Could possibly have it take a parameter, and do the heavy lifting behind the scenes:

typedef NS_ENUM(NSUInteger, BONFontFeature) {
    BONFontFeatureUnknown = 0,
    BONFontFeatureSmallCaps,
    BONFontFeatureMonospaceFigures,
    ...
}

+ (BOOL)font:(UIFont *)font supportsFeature:(BONFontFeature)feature;

Support character alternates

Some fonts have alternate glyphs for some characters. These include standard kinds like small caps and superscripts/subscripts, and also include stylistic alternates for different uses (e.g. different ® for headline and body text). BonMot should have a way to query which of these is are available in a font, and to enable easy use of them if they are available. The querying part can be done using the C functions in Core Text.

Generate debug strings

It can be difficult to debug advanced attributed strings, because certain characters (image attachments, various kinds of white space or zero-width characters, Unicode character) are hard to decipher in -[NSAttributeString description]’s output. BonMot should be able to output debug strings like this (features labeled for emphasis):

                                                    ↓ no need to call out normal inner spaces
[24×36 px attached image][non-breaking thin space]My Super Duper String[Trailing Space]
 ↑ image attachments      ↑ proper Unicode names of whitespace chars    ↑ hard-to-see characters

It should also be able to generate an Objective-C (or Swift?) line of code that would use a format string to recreate this string, for use in unit tests or for debugging purposes.

Make it easy to use special characters

To use characters like non-breaking thin spaces and other difficult-to-type-and-also-to-see symbols, you usually have to consult a Unicode reference and then include an obtuse Unicode code point in your string. BonMot should make it easy to add special characters to strings by providing a convenient API to access these characters. It should be easy to add these characters in the context of concatenating attributed strings. For example, you might want to make a string like this:

[image][non-breaking thin space]Some Text[thin space][image][non-breaking thin space]More Text

This typically takes multiple join/concatenate passes, with obscure Unicode characters or wordy abstractions. BonMot should make the code to generate strings like this concise and readable.

Tinting of images inserted into strings

Attributed strings can color their text, so they should be able to tint their images as well. You can't use UIKit’s tintColor property on UIImage directly, so BonMot should include the ability to arbitrarily tint images.

Easily add properties to a substring of an existing string

Given this string:

The quick brown fox jumped over the lazy red dog.

If you want to make the color words be different colors using BonMot, you would have to construct the string out of the following components:

  • The quick[space]
  • brown (colored brown)
  • [space]fox jumped over the lazy[space]
  • red (colored red)
  • [space]dog.

The alternative is to use BonMot to generate attributes, then apply those attributes to ranges of a mutable copy of the attributed string yourself. BonMot may be able to streamline this process.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.