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

Change list rendering to support nicer output when alignment is :both #42

Open
a-macnamara opened this issue Jun 2, 2016 · 7 comments

Comments

@a-macnamara
Copy link

I can include a new line break within a list (so that a given list item looks like it spans multiple paragraphs) like so:

Example

docx.ol do
  li do
    text "This is the first list item."
    br
    br
    text "This is the same first list item, but a new 'paragraph.'"
    br
  end
  li do
    text "This is the second list item."
  end
end

With this code, Caracal creates a document.xml that looks something like (for the first list item):

...
        <w:p w:rsidP="00000000" w:rsidRDefault="00000000" w:rsidR="00000000" w:rsidRPr="00000000" w:rsidDel="00000000">
            <w:pPr>
                <w:numPr>
                    <w:ilvl w:val="0"/>
                    <w:numId w:val="1"/>
                </w:numPr>
                <w:ind w:left="1440" w:hanging="719"/>
                <w:contextualSpacing w:val="1"/>
                <w:rPr>
                    <w:u w:val="none"/>
                </w:rPr>
            </w:pPr>
            <w:r w:rsidR="00000000" w:rsidRPr="00000000" w:rsidDel="00000000">
                <w:rPr>
                    <w:rtl w:val="0"/>
                </w:rPr>
                <w:t xml:space="preserve"/>
            </w:r>
            <w:r w:rsidR="00000000" w:rsidRPr="00000000" w:rsidDel="00000000">
                <w:rPr>
                    <w:rtl w:val="0"/>
                </w:rPr>
                <w:t xml:space="preserve">This is the first list item.</w:t>
            </w:r>
            <w:r>
                <w:br/>
            </w:r>
            <w:r>
                <w:br/>
            </w:r>
            <w:r w:rsidR="00000000" w:rsidRPr="00000000" w:rsidDel="00000000">
                <w:rPr>
                    <w:rtl w:val="0"/>
                </w:rPr>
                <w:t xml:space="preserve">This is the same first list item, but a new 'paragraph.'</w:t>
            </w:r>
            <w:r>
                <w:br/>
            </w:r>
        </w:p>
...

But when my Normal text style includes "align: :both", the text is "Justified" in such a way that Word wraps the last line of each "paragraph" that comprises a list item by padding spaces between the words with an ugly amount of space. See screenshot:

bad-justify

Within Word itself, you can get around this by entering a carriage return at the end of the first list item and removing the blank list that gets created. What Word does in the generated XML is something like (Word 2010 for Windows):

...
        <w:p w:rsidR="00666E17" w:rsidRDefault="00666E17">
            <w:pPr>
                <w:numPr>
                    <w:ilvl w:val="0"/>
                    <w:numId w:val="1"/>
                </w:numPr>
                <w:ind w:hanging="719"/>
                <w:contextualSpacing/>
            </w:pPr>
            <w:r>
                <w:t>This is the first list item.</w:t>
            </w:r>
        </w:p>
        <w:p w:rsidR="00666E17" w:rsidRDefault="00666E17" w:rsidP="00666E17">
            <w:pPr>
                <w:ind w:left="1440"/>
                <w:contextualSpacing/>
            </w:pPr>
            <w:r>
                <w:br/>
            </w:r>
            <w:bookmarkStart w:id="0" w:name="_GoBack"/>
            <w:bookmarkEnd w:id="0"/>
            <w:r>
                <w:t>This is the same first list item, but a new 'paragraph.'</w:t>
            </w:r>
        </w:p>
...

Essentially, Word starts a w:p with the list property for the first paragraph of the first list item, then starts a new w:p with no list property for the second paragraph of the first list item.

Does Caracal currently support something like this? If not, I'm willing to try adding it.

@jdugan
Copy link
Contributor

jdugan commented Jun 7, 2016

It doesn't support it now, no. And, honestly, I'm conflicted about what Word is doing here. You're certainly welcome to work up a pull request, but I'm concerned that the implementation is going to be messy (through no fault of your own, of course!).

As things stand, Caracal, like Word, treats the list_item model as a subclass of the paragraph model. It's just a paragraph with special numbering and indentation behavior.

Word seems to be treating a list item as a paragraph unless it includes one or more line feeds, in which case it magically transforms into multiple paragraphs. It's a bit of a muddy implementation, in my view.

BUT, that muddiness can all be hidden in the Caracal renderer, from which the programmer is completely abstracted. So, as long as the implementation does not put cognitive burden on the programmer and doesn't yield an incomprehensible renderer, I think it'll probably be okay.

@a-macnamara
Copy link
Author

I'm trying to think of how to implement the programmatic interface. Essentially, instead of having two paragraphs corresponding to the two li elements in my example above, maybe there could be a new class that's at the same level as li where the renderer essentially ignores the list style properties. Something like defining a new list type called li_nolist or something like that?:

docx.ol do
  li do
    text "This is the first list item."
    br
  end
  li_nolist do
    text "This is the same first list item, but a new 'paragraph.'"
    br
  end
  li do
    text "This is the second list item."
  end
end

Then the renderer would handle the creation of the three separate paragraphs and note that the second one shouldn't have the list styles applied. Is this what you were thinking of?

@jdugan
Copy link
Contributor

jdugan commented Jun 7, 2016

To me, this creates too much cognitive burden for the programmer. I'd leave the DSL interface exactly as it is.

What I'd focus on instead is seeing if we can change the rendering method to handle run arrays with/without break models differently.

@a-macnamara
Copy link
Author

Hmm. Not sure I agree re: cognitive burden - you can create this same type of markup in Word as well, with a "break" keystroke rather than explicitly creating a new paragraph as I described above. I just happen to think it's really ugly when you have justified text.

But if you're sure you want to approach it this way, happy to try to muck around the renderer to see if it could make the "pretty" markup by default - i.e., when it detects align: :both and br tags within a list item. Can you confirm?

@jdugan
Copy link
Contributor

jdugan commented Jun 7, 2016

I guess what I'm saying is I don't want Caracal users to need to know what Word does under the hood to get what would look like the behavior any reasonable Caracal user would expect without having to do anything special...because that's how break tags work.

In other words, I'm advocating from the perspective of Caracal. Most Caracal users don't really know anything about Word rendering behavior, and Caracal's value is that it allows programmers to maintain that lack of deep knowledge. Instead, programmers leverage what they already understand deeply--HTML.

I'm suggesting (and I could be thinking about this wrongly--feel free to push back) that we treat all breaks inside list item models as needing to trigger the new-paragraph-without-a-list-marker behavior you discovered in your investigation. I don't see any downside to rendering this way for left-, right-, or center-aligned list items, too.

That solves your problem for fully justified list items, doesn't harm other justification options, and so, as a result, would introduce less modality to the renderer (because you wouldn't even care about justification anymore--only the presence of break models).

@a-macnamara
Copy link
Author

OK, I'm game for that. I think I might see how to enhance render_listitem to detect br models and render appropriately. Nested lists might be difficult but let me do some testing.

@a-macnamara
Copy link
Author

created pull request #55

@jdugan jdugan changed the title New Paragraph within List Change list rendering to support nicer output when alignment is :both Dec 31, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants