10 |
11 | #import "DTCoreText.h"
12 |
13 | #endif
--------------------------------------------------------------------------------
/Demo/Resources/APOD.html:
--------------------------------------------------------------------------------
1 | Newline Spaces and BaseURL Handling
2 | This HTML has text beginning after ending tags on new lines. These need to turn into spaces. Also the HTML links are relative links, this tests if they get turned into links relative to the supplied BaseURL
3 | The remarkable view
5 | follows the locations of this galaxy's
6 | once and future stars .
8 |
9 | In reddish hues, image data from the large
10 | Herschel infrared
11 | observatory traces enormous lanes of dust,
12 | warmed by stars, sweeping along Andromeda's spiral arms.
13 |
14 | The dust, in conjunction with the galaxy's interstellar gas,
15 | comprises the raw material for future
16 | star formation .
17 |
18 | X-ray data from the XMM-Newton
19 | observatory in blue
20 | pinpoint Andromeda's X-ray binary
21 | star systems.
22 |
23 | These systems likely contain neutron stars or stellar mass
24 | black holes that represent final stages in stellar evolution.
25 |
26 | More than twice the size of our own Milky Way ,
27 | the Andromeda Galaxy is over 200,000 light-years across.
--------------------------------------------------------------------------------
/Demo/Resources/About.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
DTCoreText consists of two portions:
5 |
6 | Parsing HTML and creating NSAttributedStrings
7 | UI Classes for properly displaying these
8 |
9 |
This page demonstrates a DTAttributedTextView being loaded from a XIB. You can see how this line wraps if you rotate the device.
10 |
11 | For example you could create a rich text about view like this here
12 | Note: You need to disable auto-layout on view controllers loading views from XIB because at present DTCoreText is not yet able to dynamically re-layout in auto-layout views.
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Demo/Resources/Alignment.html:
--------------------------------------------------------------------------------
1 | Text Alignment
2 | Supported are all text alignment options via CSS text-align or the center tag.
3 | text-align: left, right, center, justify, inherit
4 |
5 | Examples
6 |
7 | Right
Center Left
8 |
9 | Non-Justified
10 | This is normal text, naturally aligned
11 | Proin lectus nisl, volutpat non aliquet id, suscipit sed est. Maecenas vitae metus eget nulla mattis bibendum a a dolor. Fusce vestibulum velit hendrerit nunc egestas non ullamcorper ipsum sagittis. Praesent dui sapien, egestas sed tincidunt vitae, posuere eu neque. Donec faucibus felis sed magna cursus in faucibus odio aliquam. Curabitur elit urna, ullamcorper ut placerat vitae, posuere sed nisl. Maecenas ac tellus nulla, a commodo purus. Suspendisse porta vulputate volutpat. Integer sodales turpis vitae ante sodales tempor. Cras iaculis accumsan ante, sed interdum sem faucibus vel. Aenean tincidunt eleifend elit at porta. Aenean sodales lacus quis lacus gravida consectetur. Sed at ligula ut diam porta auctor. Nunc libero mauris, feugiat id gravida sed, blandit non neque. Suspendisse ac mauris urna. Vivamus lacus ipsum, tincidunt nec laoreet quis, convallis id purus. Ut vehicula lobortis erat in viverra. Ut ut tellus eget ipsum malesuada dignissim. Donec quis dolor erat, id adipiscing ipsum. Donec vitae sagittis turpis.
12 |
13 |
14 | Justified
15 | Justified Text is ideal for articles and books because the left and right border appears visually the same
16 |
17 | Proin lectus nisl, volutpat non aliquet id, suscipit sed est. Maecenas vitae metus eget nulla mattis bibendum a a dolor. Fusce vestibulum velit hendrerit nunc egestas non ullamcorper ipsum sagittis. Praesent dui sapien, egestas sed tincidunt vitae, posuere eu neque. Donec faucibus felis sed magna cursus in faucibus odio aliquam. Curabitur elit urna, ullamcorper ut placerat vitae, posuere sed nisl. Maecenas ac tellus nulla, a commodo purus. Suspendisse porta vulputate volutpat. Integer sodales turpis vitae ante sodales tempor. Cras iaculis accumsan ante, sed interdum sem faucibus vel. Aenean tincidunt eleifend elit at porta. Aenean sodales lacus quis lacus gravida consectetur. Sed at ligula ut diam porta auctor. Nunc libero mauris, feugiat id gravida sed, blandit non neque. Suspendisse ac mauris urna. Vivamus lacus ipsum, tincidunt nec laoreet quis, convallis id purus. Ut vehicula lobortis erat in viverra. Ut ut tellus eget ipsum malesuada dignissim. Donec quis dolor erat, id adipiscing ipsum. Donec vitae sagittis turpis.
18 |
19 |
--------------------------------------------------------------------------------
/Demo/Resources/ArabicTest.html:
--------------------------------------------------------------------------------
1 | Arabic Text
2 | Here are some examples of Arabic and RTL text. You are welcome to add additional samples as I don't understand any RTL languages
3 | Ligation
4 | Something about Ligation, I have no idea what this is about
5 | بِسۡمِ ٱللَّهِ ٱلرَّحۡمَٰنِ ٱلرَّحِيمِ
6 | بسم الله الرحمن الرحيم
7 | Justified RTL Text
8 | Using justified alignment should cause the last line in a paragraph or lines that are too short to be right-aligned
9 | بسم الله الرحمن الرحيم لرحمن بسم الله الرحمن الرحيم لرحمن الرحيم بسم الله الرحمن الرحيم لرحمن بسم الله الرحمن ا لرحيم لرحمن الرحيم
--------------------------------------------------------------------------------
/Demo/Resources/CoreTextIssues.html:
--------------------------------------------------------------------------------
1 | Core Text Bugs
2 | Bold for Chinese Glyphs
3 | This is a bug that was present before iOS 6, the Chinese glyphs in the following line would be bold if the locale was set to Chinese due to an incorrect entry in the global font cascade table. Filed as rdar://11262229
4 | English and 中文 -- Chinese characters
5 |
6 | Italic for Chinese Glyphs in Fallback
7 | 东方盖饭
8 | 东方盖饭
9 |
10 | Extra space above lines with whitespace glyphs
11 | Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla
12 | Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla Bla bla
--------------------------------------------------------------------------------
/Demo/Resources/CurrentTest.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
4 |
5 |
6 |
7 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
8 |
9 |
10 |
11 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
12 |
13 |
14 |
15 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
16 |
--------------------------------------------------------------------------------
/Demo/Resources/EmojiTest.html:
--------------------------------------------------------------------------------
1 | Here is a Smiley: 😄 and Mr. Poop: 💩
--------------------------------------------------------------------------------
/Demo/Resources/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Demo/Resources/Icon.png
--------------------------------------------------------------------------------
/Demo/Resources/Icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Demo/Resources/Icon@2x.png
--------------------------------------------------------------------------------
/Demo/Resources/Image.html:
--------------------------------------------------------------------------------
1 | Image Handling
2 | Some basic image handling has been implemented
3 | Inline
4 | So far images work inline, sitting on the line's baseline. There is a workaround in place that if an image is more than twice as high as the surrounding text it will be treated as it's own block.
5 | Block
6 | There is a known issue with images as blocks, outside of p tags.
7 |
8 | An Image outside of P is treated as a paragraph
9 | The previous image has float style. As a Workaround a newline is added after it until we can support floating in the layouting. This is done if the inline image is more than 5 times as large as the current font pixel size. This should allow small inline images, like smileys to stay in line, while most float images would probably be larger than this.
10 | Supported Attributes
11 |
12 | width , height in pixels
13 | src with a local file path relative to the app bundle
14 |
15 | Supported Image Formats
16 | According to Apple the following image formats are supported for use with UIImage:
17 |
18 | png
19 | tif, tiff
20 | jpeg, jpg
21 | gif
22 | bmp, bmpf
23 | ico
24 | cur
25 | xbm
26 |
27 | Vertical Alignment
28 | Limited support for the CSS vertical-align tag exists
29 | Baseline:
30 | text-top:
31 | text-bottom:
32 | middle:
33 | Data Source
34 | Base64 encoded data SRC is supported, for example this red dot:
37 | Another example:
41 |
42 | Remote Images
43 | Images can also be loaded from remote URLs, even without specifying a size in the HTML. The code demonstrates how to update the DTTextAttachment's display size after download and triggering a re-layout.
44 |
45 |
--------------------------------------------------------------------------------
/Demo/Resources/LineHeight.html:
--------------------------------------------------------------------------------
1 | Line Height
2 | This demonstrates setting of different line heights. Note: Internally this is achieved by setting the minimum and maximum line height in the paragraph style. The paragraph style line height multiplier is ignored.
3 | Relative Line Heights
4 | Font Size 25px; Line Height: normal
5 | Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg
6 | Font Size 25px; Line Height: 150%
7 | Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg
8 | Font Size 25px; Line Height: 2
9 | Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg
10 |
11 | Absolut Line Heights
12 |
13 | Font Size 25px; Line Height: 15px
14 | Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg
15 | Font Size 25px; Line Height: 25px
16 | Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg
17 | Font Size 25px; Line Height: 40px
18 | Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg Xg
19 |
--------------------------------------------------------------------------------
/Demo/Resources/Objects.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 | Custom Objects
10 | This demonstrates usage of the <object> tag for embedding your own views
11 |
12 | or
13 | These views are writting in HTML like this:
14 | <object style="display:inline;margin-bottom:1em;" someColorParameter="red" width=100 height=20></object>
15 | You provide your own custom view in the -attributedTextContentView:viewForAttachment:frame: method.
16 | if (attachment isKindOfClass:[DTTextAttachmentObject class])
17 | {
18 | // somecolorparameter has a HTML color
19 | UIColor *someColor = [UIColor colorWithHTMLName:[attachment.attributes objectForKey:@"somecolorparameter"]];
20 |
21 | UIView *someView = [[UIView alloc] initWithFrame:frame];
22 | someView.backgroundColor = someColor;
23 | someView.layer.borderWidth = 1;
24 | someView.layer.borderColor = [UIColor blackColor].CGColor;
25 |
26 | return someView;
27 | }
28 |
29 | Object tags can access their childNodes
30 |
31 | <object height=100 width=100>
32 | <special stuff="bla" />
33 | </object>
34 |
35 |
36 |
37 |
38 |
39 |
40 | When creating the custom view for this object you access the text attachment childNodes to get special information you have put there in addition to the attributes
41 |
--------------------------------------------------------------------------------
/Demo/Resources/Oliver.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Demo/Resources/Oliver.jpg
--------------------------------------------------------------------------------
/Demo/Resources/Oliver@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Demo/Resources/Oliver@2x.jpg
--------------------------------------------------------------------------------
/Demo/Resources/README.html:
--------------------------------------------------------------------------------
1 | NSAttributedString HTML Additions
2 | Introduction
3 | This project aims to duplicate the methods present on Mac OSX which allow creation of NSAttributedString from HTML code.
4 | This is useful for drawing simple rich text - like this document - without having to use a web view.
5 |
6 | Hi! I'm Oliver and I appreciate your help!
7 | Features
8 | At present the following tags are supported :
9 | Headers H1 - H6 Paragraphs: P Bold: B , STRONG Italic: I , EM
10 | Underline U
11 | Superscript SUP and Subscript SUB , e.g. e = mc2
12 | Strike Out DEL , e.g. Something Removed or STRIKE e.g. Something Striked
13 | FONT (face,color and size 1-7)
14 | Horizontal Rule HR (coloring via background-color style, simplified)
15 | Hyperlinks A (Formatting only, clickable as custom view)
16 | Unordered Lists LI
17 | Ordered Lists OL
18 | Currently attributes are inherited from enclosed tags via brute force. I don't know if this is accurate.
19 | Known Differences
20 | In many aspects DTCoreText is superior to the Mac version of generating NSAttributedStrings from HTML. These become apparent in the MacUnitTest where the output from both is directly compared. I am summarizing them here for references.
21 | In the following "Mac" means the initWithHTML: methods there, "DTCoreText" means DTCoreText's initWithHTML and/or DTHTMLAttributedStringBuilder
22 |
23 | Mac does not support the video tag, DTCoreText does.
24 | DTCoreText is able to synthesize small caps by putting all characters in upper case and using a second smaller font for lowercase characters.
25 | I suspect that Mac makes use of the -webkit-margin-* CSS styles for spacing the paragraphs, DTCoreText only uses the -webkit-margin-bottom and margin-bottom at present.
26 | Mac supports CSS following addresses, e.g. "ul ul" to change the list style for stacked lists. DTCoreText does not support that and so list bullets stay the same for multiple levels.
27 |
28 |
29 | Please Help!
30 | If you find brief test cases where the created NSAttributedString differs from the version on OSX please send them to us!
31 | Also there are many small things that you could help this project with. You can either implement these yourself or sponsor their development.
32 | Follow @cocoanetics on Twitter
33 | This code is covered by a BSD License. © 2011 Oliver Drobnik
34 |
--------------------------------------------------------------------------------
/Demo/Resources/Subviews.html:
--------------------------------------------------------------------------------
1 | Custom Subviews for Hyperlinks
2 | You can use the provided DTLinkButton view as custom subview for glyph runs that make up a hyperlink. Multiple glyph runs in the same line are merged for one single subview. A hyperlink wrapping over several lines are multiple buttons which are linked via a GUID so that they highlight together
3 | Here's an example involving multiple gylph runs resulting from Chinese characters: Here are some chinese Glyphs #草原牧马# 草原 making up a hyperlink and Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ut adipiscing massa. Aliquam vitae nibh ac dui lobortis congue in non dui. Duis hendrerit metus ut neque sodales sodales. Duis a elit nibh. Praesent risus tortor, rutrum ac lobortis in, malesuada ac turpis. Fusce rhoncus adipiscing eleifend. Nulla sed arcu erat. Cras aliquam turpis a purus vestibulum vehicula. Pellentesque at sapien id eros ornare rutrum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi quis ipsum a ante porta sodales nec nec arcu. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam ac massa diam. Nullam vehicula consequat lectus in fermentum. Praesent tortor leo, facilisis ut sagittis suscipit, consequat quis dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
4 | Here some underlined text and a hyperlink with superscripted text . As you can see the underline of the superscripted part is at a different height.
5 |
6 | Follow @cocoanetics on Twitter
7 |
--------------------------------------------------------------------------------
/Demo/Resources/TextBoxes.html:
--------------------------------------------------------------------------------
1 | Text Boxes
2 | Block-Level tags (like P or DIV) can have a padding and background color.
3 | Note: Only one level of boxing is properly supported. This is a crude workaround as CoreText does not support NSTextBlock on iOS.
4 | <p style="background-color:yellow;padding:20px;">...</p>
5 | By default the background is rectangle drawn for the entire width of the content view. There is a delegate method which you can override to do your own drawing. For example a stretchable UIImage. Or a rounded rectangle as shown here.
6 |
7 | Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
8 |
9 | Some test cases
10 | Before the list with 10px padding
11 |
12 | These items have a fixed line height of 50px Note: The line-height becomes the ascender. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
13 | After the list with 25 px padding
14 |
--------------------------------------------------------------------------------
/Demo/Resources/Video.html:
--------------------------------------------------------------------------------
1 | Video
2 | HTML5 Video
3 | This demonstrates support for the HTML5 VIDEO (once it gets implemented)
4 |
5 | Your browser doesn't support the video tag. You can download the video here.
6 |
7 |
8 |
9 | To Do
10 |
11 | Add Rotation when video in fullscreen - there's a bug causing the navigation bar to shift under the status bar if Rotation is enabled
12 | Support for the different kinds of attributes to map to properties of media player
13 | Hide text contained in recognized tags
14 |
15 |
16 | YouTube in IFRAME
17 | VIDEO
--------------------------------------------------------------------------------
/Demo/Resources/XB Niloofar.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Demo/Resources/XB Niloofar.ttf
--------------------------------------------------------------------------------
/Demo/Resources/XB NiloofarBd.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Demo/Resources/XB NiloofarBd.ttf
--------------------------------------------------------------------------------
/Demo/Resources/css.css:
--------------------------------------------------------------------------------
1 | h1{
2 | margin: 0px;
3 | direction:rtl;
4 | text-align:right;
5 | }
6 | .s2{
7 | color: #000000;
8 | font-size: 68.7500%;
9 | font-style: normal;
10 | font-variant: normal;
11 | font-weight: normal;
12 | letter-spacing: 0.0000em;
13 | margin-bottom: 2.3148%;
14 | margin-top: 0.0000%;
15 | padding-left: 0.0000%;
16 | padding-right: 0.0000%;
17 | text-align: left;
18 | text-decoration: none;
19 | text-indent: 0.0000%;
20 | text-transform: none;
21 | }
22 | .s18{
23 | font-size: 81.2500%;
24 | text-align: center;
25 | }
26 | .c10{
27 | background: #FFFFFF;
28 | }
29 |
--------------------------------------------------------------------------------
/Demo/Resources/icon_smile.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Demo/Resources/icon_smile.gif
--------------------------------------------------------------------------------
/Demo/Resources/styles.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | CSS Styles Support
4 | Currently CSS styling is supported inline in tags, and via simple rules.
5 | For example:
6 | <p style="color:red; font-size: 30px;text-decoration:underline;">Some fancy text</p>
7 | Some fancy text
8 | This way you can affect the way hyperlinks are decorated: @cocoanetics versus @cocoanetics
9 |
10 | CSS Rules
11 |
12 | One or more style blocks are merged into a style sheet. Multiple matching styles are combined in this order, later styles overriding earlier ones.
13 |
14 | Tag Name
15 | Class Name (multiple classes possible)
16 | Class Name + Tag Name
17 | Tag ID
18 | Local Style attribute of Tag
19 |
20 | Not yet implemented are pseudo-selectors (first child).
21 |
22 | Supported Attributes
23 |
24 | color - names (red) or hex (#FF0000) or rbg rgb(255, 0, 0);
25 | decoration - underline , line-through
26 | font-size - specified in pixels (12px)
27 | font-family - to specify the postscript name of a family like Courier
28 | font-style - normal, inherit, italic , oblique
29 | font-weight - normal, bold
30 | letter-spacing - tighter or wider
31 |
32 |
33 | Font Families
34 |
35 |
serif
36 |
sans-serif
37 |
monospace
38 |
cursive
39 |
fantasy
40 |
41 |
42 | Text Shadows
43 | The text-shadow property is supported.
44 | Text with Shadow
45 | Embossed
46 | Glowing
47 | Multiple Shadows
50 | Text with Shadow
51 | OUTLINE
52 |
53 |
54 |
--------------------------------------------------------------------------------
/Demo/Source/AutoLayoutDemoViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // AutoLayoutDemoViewController.h
3 | // DTCoreText
4 | //
5 | // Created by David Whetstone on 5/8/15.
6 | // Copyright (c) 2015 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | @interface AutoLayoutDemoViewController : UIViewController
13 | @property (nonatomic, strong) id fileName;
14 | @end
--------------------------------------------------------------------------------
/Demo/Source/AutoLayoutDemoViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // AutoLayoutDemoViewController.m
3 | // DTCoreText
4 | //
5 | // Created by David Whetstone on 5/8/15.
6 | // Copyright (c) 2015 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "AutoLayoutDemoViewController.h"
10 |
11 | @interface AutoLayoutDemoViewController ()
12 |
13 | @property (nonatomic, DT_WEAK_PROPERTY) IBOutlet DTAttributedTextContentView *textView;
14 | @end
15 |
16 | @implementation AutoLayoutDemoViewController
17 |
18 | - (void)viewDidLoad {
19 |
20 | [super viewDidLoad];
21 |
22 | NSString *html = @"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
23 | NSData *data = [html dataUsingEncoding:NSUTF8StringEncoding];
24 | self.textView.attributedString = [[NSAttributedString alloc] initWithHTMLData:data documentAttributes:NULL];
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/Demo/Source/CoreTextDemoAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoAppDelegate.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 1/9/11.
6 | // Copyright 2011 Drobnik.com. All rights reserved.
7 | //
8 |
9 | @class DemoTextViewController;
10 |
11 | @interface CoreTextDemoAppDelegate : NSObject
12 | {
13 | UIWindow *_window;
14 | UINavigationController *_navigationController;
15 | }
16 |
17 | @property (nonatomic, strong) UIWindow *window;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/Demo/Source/CoreTextDemoAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoAppDelegate.m
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 1/9/11.
6 | // Copyright 2011 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "CoreTextDemoAppDelegate.h"
10 | #import "DemoSnippetsViewController.h"
11 |
12 | #import "DTCoreText.h"
13 | #import "UIView+DTDebug.h"
14 |
15 | @implementation CoreTextDemoAppDelegate
16 |
17 | @synthesize window = _window;
18 |
19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
20 | {
21 | // register a custom class for a tag
22 | [DTTextAttachment registerClass:[DTObjectTextAttachment class] forTagName:@"oliver"];
23 |
24 | // preload font matching table
25 | [DTCoreTextFontDescriptor asyncPreloadFontLookupTable];
26 |
27 | // for debugging, we make sure that UIView methods are only called on main thread
28 | [UIView toggleViewMainThreadChecking];
29 |
30 | // Create window
31 | _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
32 |
33 | // Create the view controller
34 | DemoSnippetsViewController *snippetsViewController = [[DemoSnippetsViewController alloc] init];
35 | _navigationController = [[UINavigationController alloc] initWithRootViewController:snippetsViewController];
36 |
37 | // Display the window
38 | _window.rootViewController = _navigationController;
39 | [_window makeKeyAndVisible];
40 |
41 | return YES;
42 | }
43 |
44 |
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/Demo/Source/DemoAboutViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoAboutViewController.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 3/4/13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DemoAboutViewController : UIViewController
12 |
13 | @property (nonatomic, DT_WEAK_PROPERTY) IBOutlet DTAttributedTextView *attributedTextView;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Demo/Source/DemoAboutViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoAboutViewController.m
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 3/4/13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "DemoAboutViewController.h"
10 |
11 | @interface DemoAboutViewController ()
12 |
13 | @end
14 |
15 | @implementation DemoAboutViewController
16 |
17 | - (id)init
18 | {
19 | self = [super initWithNibName:@"DemoAboutViewController" bundle:nil];
20 | if (self)
21 | {
22 | // Custom initialization
23 | self.navigationItem.title = @"About DTCoreText";
24 | }
25 | return self;
26 | }
27 |
28 | - (void)viewDidLoad
29 | {
30 | [super viewDidLoad];
31 | // Do any additional setup after loading the view from its nib.
32 |
33 | NSString *path = [[NSBundle mainBundle] pathForResource:@"About" ofType:@"html"];
34 | NSData *data = [NSData dataWithContentsOfFile:path];
35 |
36 | NSDictionary *options;
37 |
38 | if (@available(iOS 13.0, *)) {
39 | options = @{DTDefaultTextColor: [UIColor labelColor], DTUseiOS6Attributes: @(YES)};
40 | } else {
41 | options = @{DTDefaultTextColor: [UIColor blackColor], DTUseiOS6Attributes: @(YES)};
42 | }
43 |
44 | NSAttributedString *attributedString = [[NSAttributedString alloc] initWithHTMLData:data options:options documentAttributes:NULL];
45 |
46 | self.attributedTextView.attributedString = attributedString;
47 | self.attributedTextView.contentInset = UIEdgeInsetsMake(10, 10, 10, 10);
48 | }
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/Demo/Source/DemoAboutViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Demo/Source/DemoSnippetsViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoSnippetsViewController.h
3 | // DTCoreText
4 | //
5 | // Created by Sam Soffes on 1/14/11.
6 | // Copyright 2011 Drobnik.com. All rights reserved.
7 | //
8 |
9 | @interface DemoSnippetsViewController : UITableViewController {
10 |
11 | NSArray *_snippets;
12 |
13 | NSCache *cellCache;
14 | }
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/Demo/Source/DemoTextViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoTextViewController.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 1/9/11.
6 | // Copyright 2011 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "DTAttributedTextView.h"
10 | #import "DTLazyImageView.h"
11 |
12 | @interface DemoTextViewController : UIViewController
13 |
14 | @property (nonatomic, strong) NSString *fileName;
15 |
16 | @property (nonatomic, strong) NSURL *lastActionLink;
17 |
18 | @property (nonatomic, strong) NSURL *baseURL;
19 |
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Demo/Source/DemoWebVideoView.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoWebVideoView.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 8/5/11.
6 | // Copyright 2011 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @class DemoWebVideoView;
13 | @class DTTextAttachment;
14 |
15 | /**
16 | Protocol for delegates of
17 | */
18 | @protocol DemoWebVideoViewDelegate
19 |
20 | @optional
21 |
22 | /**
23 | Asks the delegate if an external URL may be opened
24 | @param videoView The web video view
25 | @param url The external URL that is asked to be opened
26 | @returns `YES` if the app may be left to open the external URL
27 | */
28 |
29 | - (BOOL)videoView:(DemoWebVideoView *)videoView shouldOpenExternalURL:(NSURL *)url;
30 |
31 | @end
32 |
33 |
34 | /**
35 | The class represents a custom subview for use in to represent an embedded video.
36 |
37 | Embedded videos work by loading the video URL in a web view which iOS then replaces with the built-in media player view. The URL of the embed script depends on the service and needs to be added to the webView:shouldStartLoadWithRequest:navigationType:. You want to allow the URL for the embed script, but disallow all other requests which for example occur if a user taps on the YouTube logo. If you were to allow this type of navigation then the YouTube website would be loaded in the video view. For these scenarios there is the videoView:shouldOpenExternalURL: method in DemoWebVideoViewDelegate. If you respond with `YES` (which is default if the method is not implemented) then the URL will be opened in Safari.
38 |
39 | To add additional video services please add them in the mentioned location and submit a pull request for the addition.
40 | */
41 | @interface DemoWebVideoView : UIView
42 |
43 | /**
44 | The delegate of the video view
45 | */
46 | @property (nonatomic, DT_WEAK_PROPERTY) id delegate;
47 |
48 | /**
49 | The text attachment representing an embedded video.
50 | */
51 | @property (nonatomic, strong) DTTextAttachment *attachment;
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/Demo/Source/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 1/9/11.
6 | // Copyright 2011 Drobnik.com. All rights reserved.
7 | //
8 |
9 | int main(int argc, char *argv[]) {
10 |
11 | @autoreleasepool {
12 | int retVal = UIApplicationMain(argc, argv, nil, @"CoreTextDemoAppDelegate");
13 | return retVal;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Documentation/DTCoreText_Demo_App.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Documentation/DTCoreText_Demo_App.png
--------------------------------------------------------------------------------
/Documentation/DTCoreText_Linker_Flags.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Documentation/DTCoreText_Linker_Flags.png
--------------------------------------------------------------------------------
/Documentation/DTCoreText_Reference.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Documentation/DTCoreText_Reference.png
--------------------------------------------------------------------------------
/Documentation/DTCoreText_Search_Paths.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Documentation/DTCoreText_Search_Paths.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011, Oliver Drobnik All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are met:
5 |
6 | - Redistributions of source code must retain the above copyright notice, this
7 | list of conditions and the following disclaimer.
8 |
9 | - Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.3
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "DTCoreText",
7 | platforms: [
8 | .iOS(.v9), //.v8 - .v13
9 | .macOS(.v10_10), //.v10_10 - .v10_15
10 | .tvOS(.v9), //.v9 - .v13
11 | ],
12 | products: [
13 | .library(
14 | name: "DTCoreText",
15 | // type: .dynamic,
16 | targets: ["DTCoreText"])
17 | ],
18 | dependencies: [
19 | .package(url: "https://github.com/Cocoanetics/DTFoundation.git", from: "1.7.15"),
20 | ],
21 | targets: [
22 | .target(
23 | name: "DTCoreText",
24 | dependencies: [
25 | .product(name: "DTFoundation", package: "DTFoundation"),
26 | ],
27 | path: "Core",
28 | exclude: ["DTCoreText-Info.plist", "DTCoreText-Prefix.pch"],
29 | resources: [
30 | .copy("Source/default.css")]
31 | ),
32 | .testTarget(
33 | name: "DTCoreTextTests",
34 | dependencies: ["DTCoreText"],
35 | path: "Test/Source",
36 | resources: [
37 | .copy("Resources/AppleConverted.html"),
38 | .copy("Resources/CSSCascading.html"),
39 | .copy("Resources/CSSCascading.plist"),
40 | .copy("Resources/CSSOOMCrash.html"),
41 | .copy("Resources/CSSOOMCrash.plist"),
42 | .copy("Resources/CustomFont.plist"),
43 | .copy("Resources/Emoji.html"),
44 | .copy("Resources/Empty_and_Unclosed_Paragraphs.html"),
45 | .copy("Resources/EmptyLinesAndFontAttribute.html"),
46 | .copy("Resources/KeepMeTogether.html"),
47 | .copy("Resources/ListItemBulletColorAndFont.html"),
48 | .copy("Resources/ListTest.plist"),
49 | .copy("Resources/MalformedURL.html"),
50 | .copy("Resources/NavTag.html"),
51 | .copy("Resources/NavTag.plist"),
52 | .copy("Resources/PreWhitespace.html"),
53 | .copy("Resources/PreWhitespace.plist"),
54 | .copy("Resources/RetinaDataURL.html"),
55 | .copy("Resources/RTL.html"),
56 | .copy("Resources/SpaceBetweenUnderlines.html"),
57 | .copy("Resources/Video.plist"),
58 | .copy("Resources/WarAndPeace.plist"),
59 | .copy("Resources/WhitespaceFollowingImagePromotedToParagraph.html"),
60 | .copy("Resources/Oliver.jpg"),
61 | .copy("Resources/Oliver@2x.jpg"),
62 | ]
63 | )
64 | ]
65 | )
66 |
--------------------------------------------------------------------------------
/Readme.markdown:
--------------------------------------------------------------------------------
1 | DTCoreText
2 | ==========
3 |
4 | This project aims to duplicate the methods present on Mac OSX which allow creation of `NSAttributedString` from HTML code on iOS.
5 |
6 | The project covers two broad areas:
7 |
8 | 1. **Layouting** - Interfacing with CoreText, generating attributed strings from HTML code
9 | 2. **User Interface** - UI-related classes render these objects, specifically `DTAttributedTextView`, `DTAttributedLabel` and `DTAttributedTextCell`.
10 |
11 | This is useful for drawing simple rich text like any HTML document without having to use a web view. For text selection and highlighting (as you might need for an Editor or Reader) there is the commercial **DTRichTextEditor** component which can be purchased in the [Cocoanetics Parts Store](http://www.cocoanetics.com/parts/dtrichtexteditor/).
12 |
13 | Documentation
14 | -------------
15 |
16 | Documentation can be [browsed online](https://docs.cocoanetics.com/DTCoreText) or installed in your Xcode Organizer via the [Atom Feed URL](https://docs.cocoanetics.com/DTCoreText/DTCoreText.atom).
17 |
18 | A [Q&A](http://www.cocoanetics.com/2011/08/nsattributedstringhtml-qa/) answers some frequently asked questions.
19 |
20 | Changelog: [GitHub Releases](https://github.com/Cocoanetics/DTCoreText/releases)
21 |
22 | There is also a [Programming Guide](Documentation/Programming%20Guide-template.markdown) with a set of solutions to common problems.
23 |
24 | Follow [@cocoanetics](http://twitter.com/cocoanetics) on Twitter or subscribe to the [Cocoanetics Blog](http://www.cocoanetics.com) for news and updates.
25 |
26 | License
27 | -------
28 |
29 | It is open source and covered by a standard 2-clause BSD license. That means you have to mention *Cocoanetics* as the original author of this code and reproduce the LICENSE text inside your app.
30 |
31 | You can purchase a [Non-Attribution-License](https://www.cocoanetics.com/order/?product_id=DTCoreText) for 75 Euros for not having to include the LICENSE text.
32 |
33 | We also accept sponsorship for specific enhancements which you might need. Please [contact us via email](mailto:oliver@cocoanetics.com?subject=DTCoreText) for inquiries.
34 |
--------------------------------------------------------------------------------
/Test/MacUnitTest-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Test/MacUnitTest-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'MacUnitTest' target in the 'MacUnitTest' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #import
8 | #import
9 | #import
10 | #endif
11 |
12 | #define CGSizeValue sizeValue
13 | #define valueWithCGSize valueWithSize
14 |
--------------------------------------------------------------------------------
/Test/Resources/AppleConverted.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 | many spaces
15 |
16 |
--------------------------------------------------------------------------------
/Test/Resources/CSSCascading.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | me
69 | buzz owzers
70 |
71 |
Meow
72 |
this is a test of by tag name styles targeted by class on an ancestor.
73 |
i'm gray text
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/Test/Resources/CSSCascading.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SkipUnitTest
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Test/Resources/CSSOOMCrash.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SkipUnitTest
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Test/Resources/CustomFont.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IgnoreCase
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Test/Resources/Emoji.html:
--------------------------------------------------------------------------------
1 |
2 | FYI emoji work just fine, simply encode them as hex strings. For
3 | example, 🍁 (🍁) correctly
4 | displays a maple leaf. Even double-character emoji like
5 | 🇰🇷 (🇰 🇷) display
6 | correctly.
--------------------------------------------------------------------------------
/Test/Resources/EmptyLinesAndFontAttribute.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 | a
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Test/Resources/Empty_and_Unclosed_Paragraphs.html:
--------------------------------------------------------------------------------
1 |
2 | Next paragraph empty
3 |
4 | Next paragraph missing closing (auto-closed, resulting in one empty paragraph)
5 |
Fin
--------------------------------------------------------------------------------
/Test/Resources/KeepMeTogether.html:
--------------------------------------------------------------------------------
1 | Keep me together
--------------------------------------------------------------------------------
/Test/Resources/ListItemBulletColorAndFont.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
18 |
19 |
--------------------------------------------------------------------------------
/Test/Resources/ListTest.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IgnoreNonAlphanumericCharacters
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Test/Resources/MalformedURL.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Forgot Password?
--------------------------------------------------------------------------------
/Test/Resources/NavTag.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CSS |
5 | HTML |
6 | JavaScript |
7 | SQL
8 |
--------------------------------------------------------------------------------
/Test/Resources/NavTag.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SkipUnitTest
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Test/Resources/Oliver.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Test/Resources/Oliver.jpg
--------------------------------------------------------------------------------
/Test/Resources/Oliver@2x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cocoanetics/DTCoreText/ccbf88514fdc01bc613fe983b1516fb396ab65f1/Test/Resources/Oliver@2x.jpg
--------------------------------------------------------------------------------
/Test/Resources/PreWhitespace.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | some text
4 |
5 |
6 | source code 123
7 | 123 123
8 |
9 | more text
--------------------------------------------------------------------------------
/Test/Resources/PreWhitespace.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IgnoreNonAlphanumericCharacters
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Test/Resources/RTL.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | RTL via tag attribute
7 | RTA via style attribute
8 |
9 |
--------------------------------------------------------------------------------
/Test/Resources/SpaceBetweenUnderlines.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | a b
7 |
8 |
--------------------------------------------------------------------------------
/Test/Resources/Video.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SkipUnitTest
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Test/Resources/WarAndPeace.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SkipUnitTest
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Test/Resources/WhitespaceFollowingImagePromotedToParagraph.html:
--------------------------------------------------------------------------------
1 |
2 | 1
3 |
4 | 2
--------------------------------------------------------------------------------
/Test/Source/DTCSSListStyleTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // DTCSSListStyleTest.m
3 | // DTCoreText
4 | //
5 | // Created by Ryan Johnson on 2/19/14.
6 | // Copyright (c) 2014 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @import DTCoreText;
12 |
13 | @interface DTCSSListStyleTest : XCTestCase
14 |
15 | @end
16 |
17 | @implementation DTCSSListStyleTest
18 |
19 | - (void)testNSCodingEqual {
20 | NSDictionary *styles = @{@"list-style-type":@"none", @"list-style-position":@"inherit"};
21 | DTCSSListStyle *listStyle = [[DTCSSListStyle alloc] initWithStyles:styles];
22 |
23 | NSData *listStyleData = [NSKeyedArchiver archivedDataWithRootObject:listStyle];
24 | DTCSSListStyle *unarchivedListStyle = [NSKeyedUnarchiver unarchiveObjectWithData:listStyleData];
25 |
26 | XCTAssertTrue([listStyle isEqualToListStyle:unarchivedListStyle], @"Unarchived list styles should be equal to original");
27 | }
28 |
29 | - (void)testNSCodingNotEqual {
30 | NSDictionary *styles1 = @{@"list-style-type":@"none", @"list-style-position":@"inherit"};
31 | DTCSSListStyle *listStyle1 = [[DTCSSListStyle alloc] initWithStyles:styles1];
32 |
33 | NSDictionary *styles2 = @{@"list-style-type":@"circle", @"list-style-position":@"inherit"};
34 | DTCSSListStyle *listStyle2 = [[DTCSSListStyle alloc] initWithStyles:styles2];
35 |
36 | XCTAssertFalse([listStyle1 isEqualToListStyle:listStyle2], @"Sanity check");
37 |
38 | NSData *listStyle1Data = [NSKeyedArchiver archivedDataWithRootObject:listStyle1];
39 | DTCSSListStyle *unarchivedListStyle1 = [NSKeyedUnarchiver unarchiveObjectWithData:listStyle1Data];
40 |
41 | XCTAssertFalse([unarchivedListStyle1 isEqualToListStyle:listStyle2], @"Different list styles should remain different");
42 |
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Test/Source/DTCSSStylesheetTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // DTCSSStyleSheetTest.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 20.12.12.
6 | // Copyright (c) 2012 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DTCSSStyleSheetTest : XCTestCase
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Test/Source/DTCoreTextLayoutFrameTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // DTCoreTextLayoutFrameTest.m
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 14.11.13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "DTCoreTextTestCase.h"
10 |
11 | #import
12 |
13 | @import DTCoreText;
14 |
15 | @interface DTCoreTextLayoutFrameTest : DTCoreTextTestCase
16 |
17 | @end
18 |
19 | @implementation DTCoreTextLayoutFrameTest
20 |
21 | - (void)testVariableHeight
22 | {
23 | NSAttributedString *attributedString = [super attributedStringFromHTMLString:@"Some bold text " options:nil];
24 |
25 | DTCoreTextLayouter *layouter = [[DTCoreTextLayouter alloc] initWithAttributedString:attributedString];
26 |
27 | CGRect maxRect = CGRectMake(10, 20, 1024, CGFLOAT_HEIGHT_UNKNOWN);
28 | NSRange entireString = NSMakeRange(0, [attributedString length]);
29 | DTCoreTextLayoutFrame *layoutFrame = [layouter layoutFrameWithRect:maxRect range:entireString];
30 |
31 | CGSize sizeNeeded = [layoutFrame frame].size;
32 | CGSize sizeExpected = CGSizeMake(1024, 16);
33 |
34 | XCTAssertEqual(sizeNeeded.height, sizeExpected.height, @"Size incorrect");
35 | XCTAssertEqual(sizeNeeded.width, sizeExpected.width, @"Size incorrect");
36 | }
37 |
38 | - (void)testVariableHeightAndWidth
39 | {
40 | NSAttributedString *attributedString = [super attributedStringFromHTMLString:@"Some bold text " options:nil];
41 |
42 | DTCoreTextLayouter *layouter = [[DTCoreTextLayouter alloc] initWithAttributedString:attributedString];
43 |
44 | CGRect maxRect = CGRectMake(10, 20, CGFLOAT_WIDTH_UNKNOWN, CGFLOAT_HEIGHT_UNKNOWN);
45 | NSRange entireString = NSMakeRange(0, [attributedString length]);
46 | DTCoreTextLayoutFrame *layoutFrame = [layouter layoutFrameWithRect:maxRect range:entireString];
47 |
48 | CGSize sizeNeeded = [layoutFrame frame].size;
49 | CGSize sizeExpected = CGSizeMake(76, 16);
50 |
51 | XCTAssertEqual(sizeNeeded.height, sizeExpected.height, @"Size incorrect");
52 | XCTAssertEqual(sizeNeeded.width, sizeExpected.width, @"Size incorrect");
53 | }
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/Test/Source/DTCoreTextParagraphStyleTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // DTCoreTextParagraphStyleTest.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 2/25/13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @import DTCoreText;
12 |
13 | @interface DTCoreTextParagraphStyleTest : XCTestCase
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Test/Source/DTCoreTextTestCase.h:
--------------------------------------------------------------------------------
1 | //
2 | // DTCoreTextTestCase.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 25.09.13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | Specialized test case class for testing DTCoreText issues
13 | */
14 | @interface DTCoreTextTestCase : XCTestCase
15 |
16 | /**
17 | @name Utilities
18 | */
19 |
20 | /**
21 | Parse the HTML in the file with the give name
22 | @param testFileName The name of the test file in the OCTest bundle
23 | @returns the attributed string, generated with DTCoreText
24 | */
25 | - (NSAttributedString *)attributedStringFromTestFileName:(NSString *)testFileName;
26 |
27 | /**
28 | Parses the HTML in the given string with the optional options
29 | @param HTMLString The HTML string to parse with DTCoreText
30 | @param options The parsing options
31 | @returns the attributed string, generated with DTCoreText
32 | */
33 | - (NSAttributedString *)attributedStringFromHTMLString:(NSString *)HTMLString options:(NSDictionary *)options;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/Test/Source/DTCoreTextTestCase.m:
--------------------------------------------------------------------------------
1 | //
2 | // DTCoreTextTestCase.m
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 25.09.13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "DTCoreTextTestCase.h"
10 | #import
11 |
12 | @import DTCoreText;
13 |
14 | @implementation DTCoreTextTestCase
15 |
16 | - (NSBundle*) testBundle {
17 | #if SWIFT_PACKAGE
18 | return SWIFTPM_MODULE_BUNDLE;
19 | #else
20 | return [NSBundle bundleForClass:[self class]];
21 | #endif
22 | }
23 |
24 | - (NSAttributedString *)attributedStringFromTestFileName:(NSString *)testFileName
25 | {
26 | NSString *path = [[self testBundle] pathForResource:testFileName ofType:@"html"];
27 | NSData *data = [NSData dataWithContentsOfFile:path];
28 |
29 | DTHTMLAttributedStringBuilder *builder = [[DTHTMLAttributedStringBuilder alloc] initWithHTML:data options:nil documentAttributes:NULL];
30 | return [builder generatedAttributedString];
31 | }
32 |
33 | - (NSAttributedString *)attributedStringFromHTMLString:(NSString *)HTMLString options:(NSDictionary *)options
34 | {
35 | NSData *data = [HTMLString dataUsingEncoding:NSUTF8StringEncoding];
36 |
37 | // set the base URL so that resources are found in the resource bundle
38 | NSURL *baseURL = [[self testBundle] resourceURL];
39 |
40 | NSMutableDictionary *mutableOptions = [[NSMutableDictionary alloc] initWithDictionary:options];
41 | mutableOptions[NSBaseURLDocumentOption] = baseURL;
42 |
43 | // register a custom class for a tag
44 | [DTTextAttachment registerClass:[DTObjectTextAttachment class] forTagName:@"oliver"];
45 |
46 | DTHTMLAttributedStringBuilder *builder = [[DTHTMLAttributedStringBuilder alloc] initWithHTML:data options:mutableOptions documentAttributes:NULL];
47 | return [builder generatedAttributedString];
48 | }
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/Test/Source/DTHTMLAttributedStringBuilderTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // DTHTMLAttributedStringBuilderTest.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 25.12.12.
6 | // Copyright (c) 2012 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "DTCoreTextTestCase.h"
10 |
11 | @interface DTHTMLAttributedStringBuilderTest : DTCoreTextTestCase
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Test/Source/DTHTMLElementTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // DTHTMLElementTest.h
3 | // DTCoreText
4 | //
5 | // Created by Hubert SARRET on 11/04/13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DTHTMLElementTest : XCTestCase
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Test/Source/DTHTMLWriterTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // DTHTMLWriterTest.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 11.07.13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "DTCoreTextTestCase.h"
10 |
11 | /**
12 | Unit tests related to DTHTMLWriter
13 | */
14 | @interface DTHTMLWriterTest : DTCoreTextTestCase
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/Test/Source/DTTextBlockTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // DTTextBlockTest.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 9/29/13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "DTCoreTextTestCase.h"
10 |
11 | @interface DTTextBlockTest : DTCoreTextTestCase
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Test/Source/MacUnitTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // MacUnitTest.h
3 | // MacUnitTest
4 | //
5 | // Created by Oliver Drobnik on 22.01.12.
6 | // Copyright (c) 2012 Drobnik KG. All rights reserved.
7 | //
8 |
9 | @import XCTest;
10 |
11 | @interface MacUnitTest : XCTestCase
12 |
13 | - (void)internalTestCaseWithURL:(NSURL *)URL withTempPath:(NSString *)tempPath;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Test/Source/NSAttributedStringDTCoreTextTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSAttributedStringDTCoreTextTest.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 30.09.13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "DTCoreTextTestCase.h"
10 |
11 | @interface NSAttributedStringDTCoreTextTest : DTCoreTextTestCase
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Test/Source/NSAttributedStringHTMLTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSAttributedStringHTMLTest.h
3 | // DTCoreText
4 | //
5 | // Created by Claus Broch on 11/01/11.
6 | // Copyright 2011 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSAttributedStringHTMLTest : XCTestCase {
12 |
13 | }
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Test/Source/NSMutableAttributedStringHTMLTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSMutableAttributedStringHTMLTest.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 6/25/13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSMutableAttributedStringHTMLTest : XCTestCase
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Test/Source/NSNumberRomanNumeralsTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSNumberRomanNumeralsTest.m
3 | // DTCoreText
4 | //
5 | // Created by Kai Maschke on 26.07.16.
6 | // Copyright © 2016 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface NSNumberRomanNumeralsTest : XCTestCase
13 |
14 | @end
15 |
16 | @implementation NSNumberRomanNumeralsTest
17 |
18 | - (void)testRomanNumeralConversion {
19 | XCTAssertEqualObjects([@(1) romanNumeral], @"I");
20 | XCTAssertEqualObjects([@(5) romanNumeral], @"V");
21 | XCTAssertEqualObjects([@(9) romanNumeral], @"IX");
22 | XCTAssertEqualObjects([@(10) romanNumeral], @"X");
23 | XCTAssertEqualObjects([@(11) romanNumeral], @"XI");
24 | XCTAssertEqualObjects([@(49) romanNumeral], @"XLIX");
25 | XCTAssertEqualObjects([@(880) romanNumeral], @"DCCCLXXX");
26 | XCTAssertEqualObjects([@(3999) romanNumeral], @"MMMCMXCIX");
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/Test/Source/NSStringCSSTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSStringCSSTest.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 1/5/13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSStringCSSTest : XCTestCase
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Test/Source/NSStringHTMLTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSStringHTMLTest.h
3 | // DTCoreText
4 | //
5 | // Created by Claus Broch on 11/01/11.
6 | // Copyright 2011 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSStringHTMLTest : XCTestCase {
12 |
13 | }
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Test/Source/NSStringParagraphTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSStringParagraphTest.h
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 11.04.13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSStringParagraphTest : XCTestCase
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Test/Source/NSStringParagraphTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSStringParagraphTest.m
3 | // DTCoreText
4 | //
5 | // Created by Oliver Drobnik on 11.04.13.
6 | // Copyright (c) 2013 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "NSStringParagraphTest.h"
10 |
11 | @import DTCoreText;
12 |
13 | @implementation NSStringParagraphTest
14 |
15 | - (void)testParagraphFinding
16 | {
17 | NSString *string = @"abc\ndef\n\nghi";
18 |
19 | NSRange range = NSMakeRange(3, 1);
20 | NSUInteger begIndex;
21 | NSUInteger endIndex;
22 |
23 | // range on NL character
24 | NSRange paragraphRange = [string rangeOfParagraphsContainingRange:range parBegIndex:&begIndex parEndIndex:&endIndex];
25 | NSRange expectedRange = NSMakeRange(0, 4);
26 | XCTAssertTrue(NSEqualRanges(paragraphRange, expectedRange), @"First range");
27 | XCTAssertEqual(begIndex, (NSUInteger)0, @"First range start index");
28 | XCTAssertEqual(endIndex, (NSUInteger)4, @"First range end index");
29 |
30 | // empty range
31 | range = NSMakeRange(3, 0);
32 | paragraphRange = [string rangeOfParagraphsContainingRange:range parBegIndex:&begIndex parEndIndex:&endIndex];
33 | expectedRange = NSMakeRange(0, 4);
34 | XCTAssertTrue(NSEqualRanges(paragraphRange, expectedRange), @"Second range");
35 | XCTAssertEqual(begIndex, (NSUInteger)0, @"Second range start index");
36 | XCTAssertEqual(endIndex, (NSUInteger)4, @"Second range end index");
37 |
38 | // test empty paragraph
39 | range = NSMakeRange(8, 1);
40 | paragraphRange = [string rangeOfParagraphsContainingRange:range parBegIndex:&begIndex parEndIndex:&endIndex];
41 | expectedRange = NSMakeRange(8, 1);
42 | XCTAssertTrue(NSEqualRanges(paragraphRange, expectedRange), @"Second range");
43 | XCTAssertEqual(begIndex, (NSUInteger)8, @"Second range start index");
44 | XCTAssertEqual(endIndex, (NSUInteger)9, @"Second range end index");
45 |
46 | // range at end of string
47 | range = NSMakeRange(9, 2);
48 | paragraphRange = [string rangeOfParagraphsContainingRange:range parBegIndex:&begIndex parEndIndex:&endIndex];
49 | expectedRange = NSMakeRange(9, 3);
50 | XCTAssertTrue(NSEqualRanges(paragraphRange, expectedRange), @"Third range");
51 | XCTAssertEqual(begIndex, (NSUInteger)9, @"Third range start index");
52 | XCTAssertEqual(endIndex, (NSUInteger)12, @"Third range end index");
53 | }
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/Test/Source/Resources:
--------------------------------------------------------------------------------
1 | ../Resources
--------------------------------------------------------------------------------
/Test/Source/UIColorHTMLTest.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIColorHTMLTest.h
3 | // DTCoreText
4 | //
5 | // Created by Claus Broch on 11/01/11.
6 | // Copyright 2011 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIColorHTMLTest : XCTestCase {
12 |
13 | }
14 |
15 | - (void) testValidColorWithHexString;
16 | - (void) testColorHTMLHexString;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Test/Source/UIColorHTMLTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIColorHTMLTest.m
3 | // DTCoreText
4 | //
5 | // Created by Claus Broch on 11/01/11.
6 | // Copyright 2011 Drobnik.com. All rights reserved.
7 | //
8 |
9 | #import "UIColorHTMLTest.h"
10 |
11 | @import DTCoreText;
12 |
13 | @implementation UIColorHTMLTest
14 |
15 | - (void)testValidColorWithHexString
16 | {
17 | DTColor *htmlColor;
18 | DTColor *namedColor;
19 |
20 | namedColor = [DTColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0];
21 | htmlColor = DTColorCreateWithHexString(@"000000");
22 | XCTAssertNotNil(htmlColor, @"Failed to create black color");
23 | XCTAssertEqualObjects(namedColor, htmlColor, @"Hmmm... black is not black");
24 |
25 | namedColor = [DTColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
26 | htmlColor = DTColorCreateWithHexString(@"FFFFFF");
27 | XCTAssertNotNil(htmlColor, @"Failed to create white color");
28 | XCTAssertEqualObjects(namedColor, htmlColor, @"Hmmm... white is not white");
29 |
30 | namedColor = [DTColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0];
31 | htmlColor = DTColorCreateWithHexString(@"FF0000");
32 | XCTAssertNotNil(htmlColor, @"Failed to create red color");
33 | XCTAssertEqualObjects(namedColor, htmlColor, @"Hmmm... red is not red");
34 |
35 | namedColor = [DTColor colorWithRed:0.0 green:1.0 blue:0.0 alpha:1.0];
36 | htmlColor = DTColorCreateWithHexString(@"00FF00");
37 | XCTAssertNotNil(htmlColor, @"Failed to create green color");
38 | XCTAssertEqualObjects(namedColor, htmlColor, @"Hmmm... green is not green");
39 |
40 | namedColor = [DTColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:1.0];
41 | htmlColor = DTColorCreateWithHexString(@"0000FF");
42 | XCTAssertNotNil(htmlColor, @"Failed to create blue color");
43 | XCTAssertEqualObjects(namedColor, htmlColor, @"Hmmm... blue is not blue");
44 |
45 | namedColor = [DTColor colorWithRed:1.0 green:0.0 blue:1.0 alpha:1.0];
46 | htmlColor = DTColorCreateWithHexString(@"F0F");
47 | XCTAssertNotNil(htmlColor, @"Failed to create purple color");
48 | XCTAssertEqualObjects(namedColor, htmlColor, @"Hmmm... purple is not purple");
49 | }
50 |
51 | - (void)testColorHTMLHexString
52 | {
53 | DTColor *red = [DTColor redColor];
54 | XCTAssertEqualObjects(DTHexStringFromDTColor(red), @"ff0000");
55 |
56 | DTColor *green = [DTColor greenColor];
57 | XCTAssertEqualObjects(DTHexStringFromDTColor(green), @"00ff00");
58 |
59 | DTColor *blue = [DTColor blueColor];
60 | XCTAssertEqualObjects(DTHexStringFromDTColor(blue), @"0000ff");
61 |
62 | DTColor *white = [DTColor whiteColor];
63 | XCTAssertEqualObjects(DTHexStringFromDTColor(white), @"ffffff");
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/Test/UnitTest-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleSignature
16 | ????
17 | CFBundleVersion
18 | 1.0
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Test/UnitTest-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'UnitTest' target in the 'CoreTextExtensions' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #import
8 | #import
9 | #import "DTCoreText.h"
10 | #endif
11 |
--------------------------------------------------------------------------------
/Tests/DTCoreTextTests/DTCoreTextTests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 | @testable import DTCoreText
3 |
4 | final class DTCoreTextTests: XCTestCase {
5 | func testExample() {
6 | // This is an example of a functional test case.
7 | // Use XCTAssert and related functions to verify your tests produce the correct
8 | // results.
9 | XCTAssertEqual(DTCoreText().text, "Hello, World!")
10 | }
11 |
12 | static var allTests = [
13 | ("testExample", testExample),
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/Tests/DTCoreTextTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | #if !canImport(ObjectiveC)
4 | public func allTests() -> [XCTestCaseEntry] {
5 | return [
6 | testCase(DTCoreTextTests.allTests),
7 | ]
8 | }
9 | #endif
10 |
--------------------------------------------------------------------------------
/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import DTCoreTextTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 | tests += DTCoreTextTests.allTests()
7 | XCTMain(tests)
8 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | maven {
4 | url('http://openbakery.org/repository/')
5 | }
6 | mavenCentral()
7 | }
8 | dependencies {
9 | classpath group: 'org.openbakery', name: 'xcodePlugin', version: '0.9.+'
10 | }
11 | }
12 | apply plugin: 'xcode'
13 |
14 |
15 | xcodebuild {
16 | scheme = 'Static Library'
17 | target = 'Static Library'
18 | configuration = 'Debug'
19 |
20 |
21 | }
22 |
23 |
24 | // ---------- FTP Publish ----------
25 |
26 | repositories {
27 | mavenCentral()
28 | }
29 |
30 | configurations {
31 | ftpAntTask
32 | }
33 |
34 | dependencies {
35 | ftpAntTask("org.apache.ant:ant-commons-net:1.9.+");
36 | }
37 |
38 |
39 | ant.taskdef(
40 | name: 'ftp',
41 | classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP',
42 | classpath: configurations.ftpAntTask.asPath
43 | )
44 |
45 | task documentationUpload << {
46 | def uploadHost = 'docs.cocoanetics.com'
47 | if (project.ext.properties.containsKey("uploadHost")) {
48 | uploadHost = project.ext.uploadHost
49 | }
50 |
51 | def uploadUser = null
52 | if (project.ext.properties.containsKey("uploadUser")) {
53 | uploadUser = project.ext.uploadUser
54 | } else {
55 | uploadUser = System.console().readLine("\nPlease enter the upload user: ")
56 | }
57 |
58 | def uploadPassword = null
59 | if (project.ext.properties.containsKey("uploadPassword")) {
60 | uploadPassword = project.ext.uploadPassword
61 | } else {
62 | uploadPassword = "" + System.console().readPassword("\nPlease enter the upload server password: ")
63 | }
64 |
65 |
66 | // -------------- UPLOAD DIRECTORY -------------
67 |
68 | def uploadDirectory = 'DTCoreText'
69 | if (project.ext.properties.containsKey("uploadDirectory")) {
70 | uploadDirectory = project.ext.uploadDirectory
71 | }
72 |
73 |
74 | ant.ftp(
75 | server: uploadHost,
76 | remotedir: uploadDirectory,
77 | userid: uploadUser,
78 | password: uploadPassword,
79 | depends: true,
80 | verbose: true,
81 | passive: true) {
82 |
83 | fileset(dir: 'build/documentation/html') {
84 | include(name: '**/**')
85 | }
86 | fileset(dir: 'build/documentation/publish') {
87 | include(name: '**/**')
88 | }
89 | }
90 |
91 | }
92 |
93 |
94 | // ---------- Unit Tests ----------
95 |
96 | task continuous(dependsOn: 'test')
97 |
98 | gradle.taskGraph.whenReady { taskGraph ->
99 |
100 | if (taskGraph.hasTask(test)) {
101 | println "CONFIGURE CONTINUOUS"
102 | xcodebuild {
103 |
104 | destination {
105 | platform = 'iOS Simulator'
106 | name = 'iPad'
107 | os='7.1'
108 | }
109 |
110 | destination {
111 | platform = 'iOS Simulator'
112 | name = 'iPhone Retina (3.5-inch)'
113 | os='7.1'
114 | }
115 |
116 | destination {
117 | platform = 'iOS Simulator'
118 | name = 'iPhone Retina (4-inch)'
119 | os='7.1'
120 | }
121 |
122 | destination {
123 | platform = 'iOS Simulator'
124 | name = 'iPad Retina'
125 | os='7.1'
126 | }
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------