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

Fix google docs lists #26

Merged
merged 4 commits into from
Apr 4, 2019
Merged

Fix google docs lists #26

merged 4 commits into from
Apr 4, 2019

Conversation

kevindew
Copy link
Member

@kevindew kevindew commented Apr 3, 2019

@kevindew kevindew requested a review from emmabeynon April 3, 2019 15:38
parent.children, (element) => element.nodeName.toLowerCase() === 'li'
)
const index = Array.prototype.indexOf.call(listItems, node)
prefix = (start ? Number(start) + index : index + 1) + '. '
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid the interaction between 'start' and 'index' is confusing me, but it does look like there's more than one case to test here. Would it be possible to break this up in some way, to make it more transparent?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really want to change the code here as I want to maintain it being as close to the ported code as possible, but happy to add a test for the start condition. 2 mins.

Copy link
Member Author

@kevindew kevindew Apr 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually just tried out the start code and it does nothing for us when the markdown is converted back to govspeak so will just remove it.

Example:

HTML

<ol start=5>
  <li>item</li>
  <li>item</li>
</ol>

Converts to govspeak/md:

5.  item
6.  item

Then from govspeak to HTML:

<div class="gem-c-govspeak govuk-govspeak ">
  <ol>
     <li>item</li>
     <li>item</li>
   </ol>
</div>

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated now

Copy link
Contributor

@benthorner benthorner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarifying - I think I understand it enough to see that it works now :-). Just a few questions, which I don't think are blocking:

  • It looks like we depend on the indentation of the input HTML in order to do the actual nested. Is that right?
  • I notice the conversion actually puts 3 spaces after the number/bullet marker, which is a bit weird and different to what our toolbar generates. But then I see it's also what the origin code does, so I'm guessing we're compromising here?

@kevindew
Copy link
Member Author

kevindew commented Apr 4, 2019

Thanks for clarifying - I think I understand it enough to see that it works now :-). Just a few questions, which I don't think are blocking:

  • It looks like we depend on the indentation of the input HTML in order to do the actual nested. Is that right?

Nope, that's not the case. An input of the below still passes tests:

  const html = `
    <ol>
      <li>Parent</li>
      <ol>
        <li>Child 1</li>
    <ol>
      <li>Grand child 1</li>
      <li>Grand child 2</li>
    </ol>
        <li>Child 2</li>
        <li>Child 3</li>
      </ol>
      <li>Parent sibling</li>
    </ol>
  `
  • I notice the conversion actually puts 3 spaces after the number/bullet marker, which is a bit weird and different to what our toolbar generates. But then I see it's also what the origin code does, so I'm guessing we're compromising here?

That's a good point, we were just dealing with that before but since I've hijacked the listItem markup I can update that to match what we have (hopefully) - I'll give that a whirl.

kevindew added 3 commits April 4, 2019 11:38
When you create a nested list in Google Docs the HTML comes out
incorrectly with <ul> elements as siblings of <li> elements rather than
as children. The reason we are correcting this is we expect Google docs
to be a primary source of copy and pasted HTML.

To replicate create a list in google docs and copy. The HTML should
resemble the below:

```
 <ul style="margin-top:0pt;margin-bottom:0pt;">
    <li
      dir="ltr"
      style="list-style-type:disc;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;"
    >
      <p
        dir="ltr"
        style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"
      ><span
          style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"
        >Item 1</span></p>
    </li>
    <ul style="margin-top:0pt;margin-bottom:0pt;">
      <li
        dir="ltr"
        style="list-style-type:circle;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;"
      >
        <p
          dir="ltr"
          style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"
        ><span
            style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"
          >Item 2</span></p>
      </li>
      <ul style="margin-top:0pt;margin-bottom:0pt;">
        <li
          dir="ltr"
          style="list-style-type:square;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;"
        >
          <p
            dir="ltr"
            style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"
          ><span
              style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"
            >Item 3</span></p>
        </li>
      </ul>
    </ul>
    <li
      dir="ltr"
      style="list-style-type:disc;font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;"
    >
      <p
        dir="ltr"
        style="line-height:1.38;margin-top:0pt;margin-bottom:0pt;"
      ><span
          style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;"
        >Item 4</span></p>
    </li>
  </ul>
```

The fix for this involves treating a nested <ul> element as if it was
inside the preceding <li> at conversion point.
As with <ul> elements Google Docs also produced incorrect ordered lists
where the <ol> elements are siblings of <li> elements rather than
children. The fix for this is much the same as for unordered lists.

There is however a problem that the Google markup then breaks the
ordering of lists so they are off by one because turndown only expects a
ol to have children of type li (reasonably). To resolve this I have
ported the list item method from turndown so that we can fix it with a
change to the method.
This is a feature in turndown which is used to maintain the number an
ordered list started at. For example given the following HTML:

```
<ol start=5>
  <li>item</li>
  <li>item</li>
</ol>
```

Turndown produces:

```
5.  item
6.  item
```

This feature however doesn't add value when we are dealing with govspeak
as if we take the above markdown output and run it through govspeak we
lose those numbers and receive an output of:

```
<div class="gem-c-govspeak govuk-govspeak">
  <ol>
     <li>item</li>
     <li>item</li>
   </ol>
</div>
```
@kevindew
Copy link
Member Author

kevindew commented Apr 4, 2019

@benthorner I've set the spacing up now.

@benthorner
Copy link
Contributor

👍

Since we now handle the list markdown rather than turndown we have the
opportunity to update the indenting to be more consistent with GOV.UK
style. This sets the lists to have just one space after a marker and 3
spaces before it.

I wrestled for a bit trying to work out what should be the correct level
of indentation. Some places advise 2 characters, others 3 and others 4.
If you are working in monotype fonts it's most readable to have 2 for
ul's and 3 for ol's. As we expect users not to be typing in monotype
fonts this isn't too big a concern and 3 seems to offer a nice balance
of readability and without special cases for each list type.
@kevindew kevindew merged commit 5dbb194 into master Apr 4, 2019
@kevindew kevindew deleted the fix-gdocs-lists branch April 4, 2019 11:54
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

Successfully merging this pull request may close these issues.

2 participants