Comments (5)
Thanks for your suggestions @rajdeep, I'm going to go through my code now and see if I can use them to get around my issue. I will get back to you as soon as possible with my findings.
from proton.
hi @danielallsopp,
this is by design in iOS. In attributedString
representation, each new line is a start of a new paragraph. I am not sure I understand your question correctly as for both the cases, you should be getting a new paragraph for each line of the text. I verified this again using the following in my tests:
var list = [ListItem]()
let indent: CGFloat = 50
list.append(ListItem(text: NSAttributedString(string: "Item 1"), level: 1, attributeValue: 1))
list.append(ListItem(text: NSAttributedString(string: "Item 2"), level: 1, attributeValue: 1))
// list.append(ListItem(text: NSAttributedString(string: "Item 2", attributes: [.font: UIFont.systemFont(ofSize: 18, weight: .bold)]), level: 1, attributeValue: 1))
list.append(ListItem(text: NSAttributedString(string: "Item 3"), level: 1, attributeValue: 2))
let text = ListParser.parse(list: list, indent: indent)
print(text)
The output in terms of structure is same if you use the commented line for "Item 2" or the uncommented one.
Are you able to provide a test that can help me understand the issue better?
Also, you may consider the following function in combination with what you are using which will still allow you to get the range of text for each of the list item, which you can possibly use to append list tags:
func parse(attributedString: NSAttributedString, indent: CGFloat = 25) -> [(range: NSRange, listItem: ListItem)]
from proton.
Hi @rajdeep Thanks for getting back to me.
each new line is a start of a new paragraph
This is not the case from my tests though; if I create a list with no formatting on any of the list items, then the whole list, i.e. each list item, is sent in one paragraph block from the string.enumerateInlineContents().forEach
call, like this:
these
are
passed
in
one
paragraph {
NSColor = "<UIDynamicCatalogSystemColor: 0x600002b69000; name = labelColor>";
NSFont = "<UICTFont: 0x7f809e1a8530> font-family: \".SFUI-Regular\"; font-weight: normal; font-style: normal; font-size: 17.00pt";
NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 25, TailIndent 0, FirstLineHeadIndent 25, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n 28L,\n 56L,\n 84L,\n 112L,\n 140L,\n 168L,\n 196L,\n 224L,\n 252L,\n 280L,\n 308L,\n 336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (\n) ListIntentOrdinal 0 CodeBlockIntentLanguageHint ''";
"_listItem" = "TextEditorFormat.unorderedList";
}), enclosingRange: Optional({0, 35}))
When I parse the paragraph with ListParser
then yes, each item is extracted one at a time. This way I can easily create an unordered list in HTML, because if I know the paragraph is a list I can create opening and closing tags:
<ul>
ParseList -> Create an li for each list item
</ul>
When there is formatting on the list items then I don't get the whole list in one paragraph, i.e. in the string.enumerateInlineContents().forEach
block each line item is sent as a new paragraph which makes it impossible to know when to open and close the list with HTML tags. For example:
these
{
NSColor = "<UIDynamicCatalogSystemColor: 0x600002b69000; name = labelColor>";
NSFont = "<UICTFont: 0x7f809e1a8530> font-family: \".SFUI-Regular\"; font-weight: normal; font-style: normal; font-size: 17.00pt";
NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 25, TailIndent 0, FirstLineHeadIndent 25, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n 28L,\n 56L,\n 84L,\n 112L,\n 140L,\n 168L,\n 196L,\n 224L,\n 252L,\n 280L,\n 308L,\n 336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (\n) ListIntentOrdinal 0 CodeBlockIntentLanguageHint ''";
"_listItem" = "TextEditorFormat.unorderedList";
}), enclosingRange: Optional({0, 7}))
are{
NSColor = "<UIDynamicCatalogSystemColor: 0x600002b69000; name = labelColor>";
NSFont = "<UICTFont: 0x7f809e19e350> font-family: \".SFUI-SemiboldItalic\"; font-weight: bold; font-style: italic; font-size: 17.00pt";
NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 25, TailIndent 0, FirstLineHeadIndent 25, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n 28L,\n 56L,\n 84L,\n 112L,\n 140L,\n 168L,\n 196L,\n 224L,\n 252L,\n 280L,\n 308L,\n 336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (\n) ListIntentOrdinal 0 CodeBlockIntentLanguageHint ''";
"_listItem" = "TextEditorFormat.unorderedList";
}), enclosingRange: Optional({7, 3}))
passed{
NSColor = "<UIDynamicCatalogSystemColor: 0x600002b69000; name = labelColor>";
NSFont = "<UICTFont: 0x7f809d7ca790> font-family: \".SFUI-RegularItalic\"; font-weight: normal; font-style: italic; font-size: 17.00pt";
NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 25, TailIndent 0, FirstLineHeadIndent 25, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n 28L,\n 56L,\n 84L,\n 112L,\n 140L,\n 168L,\n 196L,\n 224L,\n 252L,\n 280L,\n 308L,\n 336L\n), DefaultTabInterval 0, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0 LineBreakStrategy 0 PresentationIntents (\n) ListIntentOrdinal 0 CodeBlockIntentLanguageHint ''";
"_listItem" = "TextEditorFormat.unorderedList";
}), enclosingRange: Optional({11, 6}))
etc.
Let me know if you need any more information and I'll try and put a test project together. Parsing the list isn't a problem, but knowing when to insert the opening and closing list tags is.
from proton.
@danielallsopp, this is by design in case of enumerateInlineContents
. How I see this being used is to get fine grain information of the contents, including text, for something like persistence to JSON or similar.
If you notice, in the example you shared, the font
for each line is different, even though paragraphStyle
is the same:
these
{
...
NSFont = "<UICTFont: 0x7f809e1a8530> **font-family: \".SFUI-Regular\";** font-weight: normal; font-style: normal; font-size: 17.00pt";
...
are{
...
NSFont = "<UICTFont: 0x7f809e19e350> font-family: \".SFUI-SemiboldItalic\"; font-weight: bold; font-style: italic; font-size: 17.00pt";
...
passed{
...
NSFont = "<UICTFont: 0x7f809d7ca790> font-family: \".SFUI-RegularItalic\"; font-weight: normal; font-style: italic; font-size: 17.00pt";
...
etc.
If you would like to get info individually, you may try one of the following:
- Create a copy of your
attributedString
and drop attributes likefont
that may be different and then, read the text back. - Use your own function using
attributedString.enumerateAttribute
on.paragraphStyle
without specifying option forlongestEffectiveRangeNotRequired
. It's because of this option that the string gets broken down when any of the attribute in given range is different. - Create your own function and split text based on newlines. Each range of text is one paragraph then and you can inspect or process each line individually per your requirement.
Also, for your purposes, can you not just use the contents parsed by ListParser
and take the ranges from that to append the list start and end tags?
Hope this helps.
If you feel I am still missing the context, I think best would be to provide a failing unit test that I can look at to understand your requirements. 🙂
from proton.
please feel to reopen this issue if any further discussion is required.
from proton.
Related Issues (20)
- How to know when EditorView is first responder? HOT 1
- Unexpected list indent when toggling list in new line that already has list item. HOT 1
- What document format supported? HOT 1
- EditorView's placeholder frame is incorrect when adjusting insets HOT 2
- Missing public init for ListItem HOT 1
- how can i selected text in some panel HOT 7
- [bug] Space rendered wider after emoji HOT 5
- Can't launch Example app, No such module 'Proton' HOT 2
- Are there likely breaking changes coming soon? HOT 8
- API for easily inserting a character at the given selection point, maintaining current style? HOT 2
- Publicly expose the underlying UIScrollView HOT 2
- Native visionOS support HOT 4
- Package fails to load HOT 1
- Editor shouldHandleKey not being called HOT 7
- Issues with non-zero line spacing HOT 2
- Editor shouldHandleKey not being called (again) HOT 3
- EditorView.attributedText problem HOT 6
- ExampleApp compilation issue HOT 1
- Is it possible to give padding to a range of text like html inline block? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from proton.