// // ZSSTextView.m // ZSSRichTextEditor // // Created by Nicholas Hubbard on 1/29/14. // Copyright (c) 2014 Zed Said Studio. All rights reserved. // #import "ZSSTextView.h" #import #define RGB(r,g,b) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:1.0f] @implementation ZSSTextView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self commonSetup]; } return self; } - (void)commonSetup { _defaultFont = [UIFont systemFontOfSize:14.0f]; _boldFont = [UIFont boldSystemFontOfSize:14.0f]; _italicFont = [UIFont fontWithName:@"HelveticaNeue-Oblique" size:14.0f]; self.font = _defaultFont; [self addObserver:self forKeyPath:NSStringFromSelector(@selector(defaultFont)) options:NSKeyValueObservingOptionNew context:0]; [self addObserver:self forKeyPath:NSStringFromSelector(@selector(boldFont)) options:NSKeyValueObservingOptionNew context:0]; [self addObserver:self forKeyPath:NSStringFromSelector(@selector(italicFont)) options:NSKeyValueObservingOptionNew context:0]; if (_italicFont == nil && ([UIFontDescriptor class] != nil)) { // This works around a bug in 7.0.3 where HelveticaNeue-Italic is not present as a UIFont option _italicFont = (__bridge_transfer UIFont*)CTFontCreateWithName(CFSTR("HelveticaNeue-Italic"), 14.0f, NULL); } self.tokens = [self solverTokens]; } - (NSArray *)solverTokens { NSArray *solverTokens = @[ [CYRToken tokenWithName:@"html_tags" expression:@"(<\\/?[a-z][^<>]*>)" attributes:@{ NSForegroundColorAttributeName : RGB(25, 0, 151)}], [CYRToken tokenWithName:@"a_tag" expression:@"(<\\/?[a][^<>]*>)" attributes:@{ NSForegroundColorAttributeName : RGB(24, 104, 10)}], [CYRToken tokenWithName:@"img_tag" expression:@"(<\\/?[img][^<>]*>)" attributes:@{ NSForegroundColorAttributeName : RGB(148, 0, 151)}], [CYRToken tokenWithName:@"html_entities" expression:@"("|&|'|<|>| |¡|¢|£|¤|¥|¦|§|¨|©|ª|«|¬|­|®|¯|°|±|²|³|´|µ|¶|·|¸|¹|º|»|¼|½|¾|¿|À|Á|Â|Ã|Ä|Å|Æ|Ç|È|É|Ê|Ë|Ì|Í|Î|Ï|Ð|Ñ|Ò|Ó|Ô|Õ|Ö|×|Ø|Ù|Ú|Û|Ü|Ý|Þ|ß|à|á|â|ã|ä|å|æ|ç|è|é|ê|ë|ì|í|î|ï|ð|ñ|ò|ó|ô|õ|ö|÷|ø|ù|ú|û|ü|ý|þ|ÿ|Œ|œ|Š|š|Ÿ|ƒ|ˆ|˜|Α|Β|Γ|Δ|Ε|Ζ|Η|Θ|Ι|Κ|Λ|Μ|Ν|Ξ|Ο|Π|Ρ|Σ|Τ|Υ|Φ|Χ|Ψ|Ω|α|β|γ|δ|ε|ζ|η|θ|ι|κ|λ|μ|ν|ξ|ο|π|ρ|ς|σ|τ|υ|φ|χ|ψ|ω|ϑ|ϒ|ϖ| | | |‌|‍|‎|‏|–|—|‘|’|‚|“|”|„|†|‡|•|…|‰|′|″|‹|›|‾|⁄|€|ℑ|℘|ℜ|™|ℵ|←|↑|→|↓|↔|↵|⇐|⇑|⇒|⇓|⇔|∀|∂|∃|∅|∇|∈|∉|∋|∏|∑|−|∗|√|∝|∞|∠|∧|∨|∩|∪|∫|∴|∼|≅|≈|≠|≡|≤|≥|⊂|⊃|⊄|⊆|⊇|⊕|⊗|⊥|⋅|⌈|⌉|⌊|⌋|〈|〉|◊|♠|♣|♥|♦|"|&|'|<|>| |¡|¢|£|¤|¥|¦|§|¨|©|ª|«|¬|­|®|¯|°|±|²|³|´|µ|¶|·|¸|¹|º|»|¼|½|¾|¿|À|Á|Â|Ã|Ä|Å|Æ|Ç|È|É|Ê|Ë|Ì|Í|Î|Ï|Ð|Ñ|Ò|Ó|Ô|Õ|Ö|×|Ø|Ù|Ú|Û|Ü|Ý|Þ|ß|à|á|â|ã|ä|å|æ|ç|è|é|ê|ë|ì|í|î|ï|ð|ñ|ò|ó|ô|õ|ö|÷|ø|Ù|Ú|Û|Ü|ý|þ|ÿ|Œ|œ|Š|š|Ÿ|ƒ|ˆ|˜|Α|Β|Γ|Δ|Ε|Ζ|Η|Θ|Ι|Κ|Λ|Μ|Ν|Ξ|Ο|Π|Ρ|Σ|Τ|Υ|Φ|Χ|Ψ|Ω|α|β|γ|δ|ε|ζ|η|θ|ι|κ|λ|μ|ν|ξ|ο|π|ρ|ς|σ|τ|υ|φ|χ|ψ|ω|ϑ|&Upsih;|ϖ| | | |‌|‍|‎|‏|–|—|‘|’|‚|“|”|„|†|‡|•|…|‰|′|″|‹|›|‾|⁄|€|ℑ|℘|ℜ|™|ℵ|←|↑|→|↓|↔|↵|⇐|&UArr;|⇒|⇓|⇔|∀|∂|∃|∅|∇|∈|∉|∋|∏|∑|−|∗|√|∝|∞|∠|∧|∨|∩|∪|∫|∴|∼|≅|≈|≠|≡|≤|≥|⊂|⊃|⊄|⊆|⊇|⊕|⊗|⊥|⋅|⌈|⌉|⌊|⌋|⟨|⟩|◊|♠|♣|♥|♦)" attributes:@{ NSForegroundColorAttributeName : [UIColor blackColor], NSFontAttributeName: self.boldFont, NSDocumentTypeDocumentAttribute: NSPlainTextDocumentType}], [CYRToken tokenWithName:@"comment" expression:@"" attributes:@{ NSForegroundColorAttributeName : RGB(31, 131, 0), NSFontAttributeName : self.italicFont }], [CYRToken tokenWithName:@"attributes" expression:@"(?<==)('|\").*?\\1(?=.*?>)" attributes:@{ NSForegroundColorAttributeName : RGB(0, 12, 255) }] ]; return solverTokens; } #pragma mark - Cleanup - (void)dealloc { [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(defaultFont))]; [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(boldFont))]; [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(italicFont))]; } #pragma mark - KVO - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:NSStringFromSelector(@selector(defaultFont))] || [keyPath isEqualToString:NSStringFromSelector(@selector(boldFont))] || [keyPath isEqualToString:NSStringFromSelector(@selector(italicFont))]) { // Reset the tokens, this will clear any existing formatting self.tokens = [self solverTokens]; } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } #pragma mark - Overrides - (void)setDefaultFont:(UIFont *)defaultFont { _defaultFont = defaultFont; self.font = defaultFont; } @end