Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add HTML fragment support #341

Merged
merged 1 commit into from

2 participants

@amro

I'm using DTRichTextEditor and needed a way to retrieve html fragments with inlined styles. Please let me know if there's something I should correct in the commit in terms of style, etc.

@Cocoanetics Cocoanetics merged commit aeb3029 into Cocoanetics:master
@Cocoanetics
Owner

Looks fine, thanks for also adding documentation.

@Cocoanetics Cocoanetics was assigned
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 13, 2013
  1. @amro

    Adds HTML fragment support (no html/head tags and inline styles) to D…

    amro authored
    …HTMLWriter and NSAttributedString+DTCoreText
This page is out of date. Refresh to see the latest.
View
7 Core/Source/DTHTMLWriter.h
@@ -24,6 +24,13 @@
*/
- (NSString *)HTMLString;
+
+/**
+ Generates a HTML fragment representation of the attributed string including inlined styles and no html or head elements
+ @returns The generated string
+ */
+- (NSString *)HTMLFragment;
+
/**
If specified then all absolute font sizes (px) will be divided by this value. This is useful if you specified a text size multiplicator when converting HTML to the attributed string you are processing.
*/
View
97 Core/Source/DTHTMLWriter.m
@@ -79,7 +79,7 @@ - (NSString *)_styleClassForElement:(NSString *)elementName style:(NSString *)st
return [NSString stringWithFormat:@"%@%d", [elementName substringToIndex:1],(int)index];
}
-- (NSString *)_tagRepresentationForListStyle:(DTCSSListStyle *)listStyle closingTag:(BOOL)closingTag
+- (NSString *)_tagRepresentationForListStyle:(DTCSSListStyle *)listStyle closingTag:(BOOL)closingTag inlineStyles:(BOOL)inlineStyles
{
BOOL isOrdered = NO;
@@ -204,13 +204,23 @@ - (NSString *)_tagRepresentationForListStyle:(DTCSSListStyle *)listStyle closing
NSString *listStyleString = [NSString stringWithFormat:@"list-style='%@';\">", typeString];
NSString *className = [self _styleClassForElement:blockElement style:listStyleString];
+ NSString *listElementString = nil;
+ if (inlineStyles) {
+ listElementString = [NSString stringWithFormat:@"<%@ style=\"%@\">", blockElement, listStyleString];
+ } else {
+ listElementString = [NSString stringWithFormat:@"<%@ class=\"%@\">", blockElement, className];
+ }
return [NSString stringWithFormat:@"<%@ class=\"%@\">", blockElement, className];
}
}
-
- (void)_buildOutput
{
+ [self _buildOutputAsHTMLFragment:NO];
+}
+
+- (void)_buildOutputAsHTMLFragment:(BOOL)fragment
+{
// reusable styles
_styleLookup = [[NSMutableDictionary alloc] init];
@@ -327,7 +337,7 @@ - (void)_buildOutput
}
// end of a list block
- [retString appendString:[self _tagRepresentationForListStyle:closingStyle closingTag:YES]];
+ [retString appendString:[self _tagRepresentationForListStyle:closingStyle closingTag:YES inlineStyles:fragment]];
[retString appendString:@"\n"];
[closingStyles removeLastObject];
@@ -345,7 +355,7 @@ - (void)_buildOutput
if (![previousListStyles containsObject:effectiveListStyle])
{
// beginning of a list block
- [retString appendString:[self _tagRepresentationForListStyle:effectiveListStyle closingTag:NO]];
+ [retString appendString:[self _tagRepresentationForListStyle:effectiveListStyle closingTag:NO inlineStyles:fragment]];
[retString appendString:@"\n"];
}
@@ -377,7 +387,12 @@ - (void)_buildOutput
if ([paraStyleString length])
{
NSString *className = [self _styleClassForElement:blockElement style:paraStyleString];
- [retString appendFormat:@"<%@ class=\"%@\">", blockElement, className];
+
+ if (fragment) {
+ [retString appendFormat:@"<%@ style=\"%@\">", blockElement, paraStyleString];
+ } else {
+ [retString appendFormat:@"<%@ class=\"%@\">", blockElement, className];
+ }
}
else
{
@@ -534,7 +549,11 @@ - (void)_buildOutput
{
NSString *className = [self _styleClassForElement:blockName style:classStyleString];
- [retString appendFormat:@" class=\"%@\"", className];
+ if (fragment) {
+ [retString appendFormat:@" style=\"%@\"", classStyleString];
+ } else {
+ [retString appendFormat:@" class=\"%@\"", className];
+ }
}
// build a HTML 5 conformant size style if set
@@ -687,7 +706,12 @@ - (void)_buildOutput
if ([fontStyle length])
{
NSString *className = [self _styleClassForElement:@"a" style:fontStyle];
- [retString appendFormat:@"<a class=\"%@\" href=\"%@\">%@</a>", className, [url relativeString], subString];
+
+ if (fragment) {
+ [retString appendFormat:@"<a style=\"%@\" href=\"%@\">%@</a>", fontStyle, [url relativeString], subString];
+ } else {
+ [retString appendFormat:@"<a class=\"%@\" href=\"%@\">%@</a>", className, [url relativeString], subString];
+ }
}
else
{
@@ -699,7 +723,12 @@ - (void)_buildOutput
if ([fontStyle length])
{
NSString *className = [self _styleClassForElement:@"span" style:fontStyle];
- [retString appendFormat:@"<span class=\"%@\">%@</span>", className, subString];
+
+ if (fragment) {
+ [retString appendFormat:@"<span style=\"%@\">%@</span>", fontStyle, subString];
+ } else {
+ [retString appendFormat:@"<span class=\"%@\">%@</span>", className, subString];
+ }
}
else
{
@@ -725,34 +754,40 @@ - (void)_buildOutput
DTCSSListStyle *closingStyle = [closingStyles lastObject];
// end of a list block
- [retString appendString:[self _tagRepresentationForListStyle:closingStyle closingTag:YES]];
+ [retString appendString:[self _tagRepresentationForListStyle:closingStyle closingTag:YES inlineStyles:fragment]];
[retString appendString:@"\n"];
[closingStyles removeLastObject];
}
while ([closingStyles count]);
}
-
- // append style block before text
- NSMutableString *styleBlock = [NSMutableString string];
-
- NSArray *keys = [[_styleLookup allKeys] sortedArrayUsingSelector:@selector(compare:)];
-
- for (NSString *oneKey in keys)
- {
- NSArray *styleArray = [_styleLookup objectForKey:oneKey];
- [styleArray enumerateObjectsUsingBlock:^(NSString *style, NSUInteger idx, BOOL *stop) {
- NSString *className = [NSString stringWithFormat:@"%@%d", [oneKey substringToIndex:1], (int)idx+1];
- [styleBlock appendFormat:@"%@.%@ {%@}\n", oneKey, className, style];
- }];
- }
-
NSMutableString *output = [NSMutableString string];
+
+ if (!fragment) {
+ // append style block before text
+ NSMutableString *styleBlock = [NSMutableString string];
+
+ NSArray *keys = [[_styleLookup allKeys] sortedArrayUsingSelector:@selector(compare:)];
+
+ for (NSString *oneKey in keys)
+ {
+ NSArray *styleArray = [_styleLookup objectForKey:oneKey];
+
+ [styleArray enumerateObjectsUsingBlock:^(NSString *style, NSUInteger idx, BOOL *stop) {
+ NSString *className = [NSString stringWithFormat:@"%@%d", [oneKey substringToIndex:1], (int)idx+1];
+ [styleBlock appendFormat:@"%@.%@ {%@}\n", oneKey, className, style];
+ }];
+ }
+
+ [output appendFormat:@"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html40/strict.dtd\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n<meta http-equiv=\"Content-Style-Type\" content=\"text/css\" />\n<meta name=\"Generator\" content=\"DTCoreText HTML Writer\" />\n<style type=\"text/css\">\n%@</style>\n</head>\n<body>\n", styleBlock];
+ }
- [output appendFormat:@"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html40/strict.dtd\">\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n<meta http-equiv=\"Content-Style-Type\" content=\"text/css\" />\n<meta name=\"Generator\" content=\"DTCoreText HTML Writer\" />\n<style type=\"text/css\">\n%@</style>\n</head>\n<body>\n", styleBlock];
[output appendString:[retString stringByAddingAppleConvertedSpace]];
- [output appendString:@"</body>\n</html>\n"];
+
+ if (!fragment) {
+ [output appendString:@"</body>\n</html>\n"];
+ }
_HTMLString = output;
}
@@ -769,6 +804,16 @@ - (NSString *)HTMLString
return _HTMLString;
}
+- (NSString *)HTMLFragment
+{
+ if (!_HTMLString)
+ {
+ [self _buildOutputAsHTMLFragment:true];
+ }
+
+ return _HTMLString;
+}
+
#pragma mark - Properties
@synthesize attributedString = _attributedString;
View
7 Core/Source/NSAttributedString+DTCoreText.h
@@ -85,6 +85,13 @@
/**
+ Encodes the receiver into a generic HTML fragment representation. Styles are inlined and no html or head tags are included.
+
+ @returns An HTML string.
+ */
+- (NSString *)htmlFragment;
+
+/**
Converts the receiver into plain text.
This is different from the `string` method of `NSAttributedString` by also erasing placeholders for text attachments.
View
9 Core/Source/NSAttributedString+DTCoreText.m
@@ -217,6 +217,15 @@ - (NSString *)htmlString
return [writer HTMLString];
}
+- (NSString *)htmlFragment
+{
+ // create a writer
+ DTHTMLWriter *writer = [[DTHTMLWriter alloc] initWithAttributedString:self];
+
+ // return it's output
+ return [writer HTMLFragment];
+}
+
- (NSString *)plainTextString
{
NSString *tmpString = [self string];
Something went wrong with that request. Please try again.