Skip to content

Commit

Permalink
Add improved spread algorithm for list items
Browse files Browse the repository at this point in the history
Closes GH-75.
Closes GH-76.

Co-authored-by: TRIAEIOU <94647023+TRIAEIOU@users.noreply.github.com>
  • Loading branch information
wooorm and TRIAEIOU committed Jan 12, 2023
1 parent 7a09ded commit 9706341
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 8 deletions.
59 changes: 51 additions & 8 deletions lib/handlers/li.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* @typedef {import('../state.js').State} State
*/

import {phrasing} from 'hast-util-phrasing'

/**
* @param {State} state
* State.
Expand Down Expand Up @@ -42,15 +44,56 @@ export function li(state, node) {
}
}

const children = state.toFlow(state.all(clone || node))
if (!clone) clone = node

const spread = spreadout(clone)
const children = state.toFlow(state.all(clone))

/** @type {ListItem} */
const result = {
type: 'listItem',
spread: children.length > 1,
checked,
children
}
state.patch(node, result)
const result = {type: 'listItem', spread, checked, children}
state.patch(clone, result)
return result
}

/**
* Check if an element should spread out.
*
* The reason to spread out a markdown list item is primarily whether writing
* the equivalent in markdown, would yield a spread out item.
*
* A spread out item results in `<p>` and `</p>` tags.
* Otherwise, the phrasing would be output directly.
* We can check for that: if there’s a `<p>` element, spread it out.
*
* But what if there are no paragraphs?
* In that case, we can also assume that if two “block” things were written in
* an item, that it is spread out, because blocks are typically joined by blank
* lines, which also means a spread item.
*
* Lastly, because in HTML things can be wrapped in a `<div>` or similar, we
* delve into non-phrasing elements here to figure out if they themselves
* contain paragraphs or 2 or more flow non-phrasing elements.
*
* @param {Element} node
* @returns {boolean}
*/
function spreadout(node) {
let index = -1
let seenFlow = false

while (++index < node.children.length) {
const child = node.children[index]

if (child.type === 'element') {
if (phrasing(child)) continue

if (child.tagName === 'p' || seenFlow || spreadout(child)) {
return true
}

seenFlow = true
}
}

return false
}
2 changes: 2 additions & 0 deletions test/fixtures/dl/index.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"": "spread can’t be losslessly translated between HTML <> markdown",
"tree": false,
"fragment": true
}
2 changes: 2 additions & 0 deletions test/fixtures/dl/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ Charlie.
* Firefox

* A web browser.

* A Red Panda.

* ```js
charlie();
```
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/ol/index.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"": "spread can’t be losslessly translated between HTML <> markdown",
"tree": false,
"fragment": true
}
10 changes: 10 additions & 0 deletions test/fixtures/ol/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
2. Alpha

3. Bravo

4. ```js
charlie();
```
Expand Down Expand Up @@ -27,23 +29,31 @@ Bar.
Baz.

1.

2. Something else

Qux.

1. Something else

2.

Quux.

1. Something else

2.

Quuux.

1. [x] Bravo

2. [ ] Charlie

3. [x] Delta

4. [ ] Echo

5. [ ] **Foxtrot**

6. [ ] **Golf**
2 changes: 2 additions & 0 deletions test/fixtures/ul/index.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"": "spread can’t be losslessly translated between HTML <> markdown",
"tree": false,
"fragment": true
}
10 changes: 10 additions & 0 deletions test/fixtures/ul/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
* Alpha

* Bravo

* ```js
charlie();
```
Expand Down Expand Up @@ -27,23 +29,31 @@ Bar.
Baz.

*

* Something else

Qux.

* Something else

*

Quux.

* Something else

*

Quuux.

* [x] Bravo

* [ ] Charlie

* [x] Delta

* [ ] Echo

* [ ] **Foxtrot**

* [ ] **Golf**

0 comments on commit 9706341

Please sign in to comment.