Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply NSParagraphStyleAttributeName to list items via listAttributes #50

Open
nateirwin opened this issue May 17, 2016 · 14 comments
Open
Assignees
Milestone

Comments

@nateirwin
Copy link

I'm trying to add consistent indentation to ordered and unordered list items coming down in a Markdown string. If I change the defaultAttributes property on the TSMarkdownParser instance, adding an NSParagraphStyleAttributeName, the indentation settings work but are applied to all of the Markdown text. What I'm hoping to do is only apply the NSParagraphStyleAttributeName to the text that's associated with a Markdown list.

Pared down code here:

NSMutableParagraphStyle *listStyle;
listStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[listStyle setDefaultTabInterval:18];
[listStyle setFirstLineHeadIndent:0];
[listStyle setHeadIndent:18];
[listStyle setLineSpacing:7.5];
[listStyle setTabStops:@[ [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft location:18 options:nil] ]];
NSString *markdown = @"## Title\n\n- Item 1\n- Item 2\n- Item 3\n\n1. Item 1\n2. Item 2\n3. Item 3\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Sed interdum tortor odio, vitae porttitor lacus dapibus non. Etiam sodales euismod sapien a porta. Vivamus lectus ipsum, ultrices vel efficitur eget, sollicitudin in libero. Duis posuere felis velit, sit amet sodales nulla pharetra gravida. Aenean non justo venenatis, auctor nibh ut, hendrerit tortor.";
TSMarkdownParser *parser = [TSMarkdownParser standardParser];

parser.defaultAttributes = @{
    // This works, but affects all of the text, including text that isn't part of a list.
    // NSParagraphStyleAttributeName: listStyle
};
parser.listAttributes = @[
    // This does not affect the styling of the list items. Perhaps it's getting overridden?
    @{ NSParagraphStyleAttributeName: listStyle }
];

NSAttributedString *string = [parser attributedStringFromMarkdown:markdown];

Hopefully this explanation makes sense. I'm an Objective-C newb.

@Coeur
Copy link
Collaborator

Coeur commented May 17, 2016

Hello @nateirwin, defaultAttributes is for the whole attributed string, and listAttributes is only for list items.

I haven't tried NSParagraphStyleAttributeName before, so I will make some tests tonight. But to make things obvious, you can try this in the mean time:

parser.listAttributes = @[
    @{ NSForegroundColorAttributeName: [UIColor redColor] }
];

@nateirwin
Copy link
Author

Hey @Coeur, thanks for getting back to me.

Adding the code from your post does work correctly, so it definitely seems like there's something going on with NSParagraphStyleAttributeName. I'll try to dig in some more, but any help is much appreciated!

@Coeur
Copy link
Collaborator

Coeur commented Jun 4, 2016

@nateirwin, did you find a reason or a workaround?

@nateirwin
Copy link
Author

Nope, no more progress on this. It isn't a show stopper for us, though it would be nice to be able to apply different styling to lists.

@Coeur Coeur self-assigned this Jun 16, 2016
@phatmann
Copy link

This seems to be an issue with NSAttributedString. Applying the paragraph style for each bulleted line does not work. Instead, the style needs to be applied across all the bulleted lines. A workaround might be to use a separate attributed string for bulleted lists.

@Coeur Coeur added this to the 3.0.0 milestone Aug 22, 2016
@kyledold
Copy link

kyledold commented Jun 7, 2017

@Coeur Any progress on this issue? or workaround?

@BobDG
Copy link

BobDG commented Jun 7, 2017

@kyledold @Coeur actually this works fine right now in my App if I simply set it for the listAttributes.
Like this:

NSMutableParagraphStyle *style = [NSMutableParagraphStyle new];
style.headIndent = 28;
NSDictionary *listAttributes = @{NSFontAttributeName:[UIFont fontWithName:kFontLatoRegular size:16.0f], NSForegroundColorAttributeName:[AppAppearance textDarkGray], NSParagraphStyleAttributeName:style};
parser.listAttributes = @[listAttributes];

So I think this issue can be closed?

@kyledold
Copy link

kyledold commented Jun 7, 2017

So my issue was setting the NSParagraphStyleAttributeName attribute for the "listAttributes" property of the parser wasn't having any effect, even after trying @BobDG's example.

The only way I could get this to work was to set the NSParagraphStyleAttributeName attribute of the "defaultAttributes" property.

@BobDG
Copy link

BobDG commented Jun 7, 2017

@kyledold hm strange, it works perfectly for me. Only for bullet lists unordered though, nut numbered lists because the regex doesn't take those into account.

@kyledold
Copy link

kyledold commented Jun 7, 2017

@BobDG which version are you using? I've got v2.1.3

@BobDG
Copy link

BobDG commented Jun 7, 2017

@kyledold me too.. what you can check is perhaps if the regex actually captures your lists by putting some logs at the right places?

@khill25
Copy link

khill25 commented Jun 9, 2017

I am also having this issue. Version 2.1.3. Things look great when applying the style to the whole string using defaultAttributes but using listAttributes doesn't seem to do anything once the string wraps.

I think this may be a mutable string bug though. I have experienced issues in the past trying to apply multiple paragraph styles to a attributed string.

Kind of a huge bummer because it makes an existing view more complicated to break out all the strings into their own labels.

@kyledold
Copy link

@khill25 @BobDG I found the only way to get NSParagraphStyleAttributeName set for list elements is to create your own version of the TSMarkdownParser object and then in the init method where you add all the parsing logic you need to replace the "addListParsingWithMaxLevel" method with the following:

+ (instancetype)standardParser {

  LURMarkDownParser *defaultParser = [self new];

  ....

  NSMutableParagraphStyle *listStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
  [listStyle setDefaultTabInterval:18];
  [listStyle setFirstLineHeadIndent:0];
  [listStyle setHeadIndent:28];

  [defaultParser addListParsingWithMaxLevel:0 leadFormattingBlock:^(NSMutableAttributedString *attributedString, NSRange range, NSUInteger level) {
    NSMutableString *listString = [NSMutableString string];
    while (--level)
     [listString appendString:@"\t"];
   [listString appendString:@"•\t"];
   [attributedString replaceCharactersInRange:range withString:listString];
	
    // Apply paragraph style attributes to string 
    [attributedString addAttributes:@{NSFontAttributeName:[UIFont fontWithName:defaultFontFamily size:16], NSParagraphStyleAttributeName: listStyle} range:range];
	
  } textFormattingBlock:^(NSMutableAttributedString *attributedString, NSRange range, NSUInteger level) {
    [LURMarkDownParser addAttributes:weakParser.listAttributes atIndex:level - 1 toString:attributedString range:range];
  }];

  .....

}

Not the cleanest solution but it works.

@BobDG
Copy link

BobDG commented Jun 12, 2017

@kyledold ok nice you got it working! If I look at the code I still don't understand why mine is working without any adaptations and that you need these changes. But I'm glad it works for you now :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants