Skip to content

Commit 122101f

Browse files
committed
Fix to not generate blank lines for phrasing roots
1 parent e812c79 commit 122101f

File tree

7 files changed

+43
-36
lines changed

7 files changed

+43
-36
lines changed

lib/handle/root.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
* @typedef {import('../types.js').Info} Info
66
*/
77

8+
import {phrasing} from 'mdast-util-phrasing'
89
import {containerFlow} from '../util/container-flow.js'
10+
import {containerPhrasing} from '../util/container-phrasing.js'
911

1012
/**
1113
* @param {Root} node
@@ -15,5 +17,9 @@ import {containerFlow} from '../util/container-flow.js'
1517
* @returns {string}
1618
*/
1719
export function root(node, _, state, info) {
18-
return containerFlow(node, state, info)
20+
// Note: `html` nodes are ambiguous.
21+
const hasPhrasing = node.children.some((d) => phrasing(d))
22+
const fn = hasPhrasing ? containerPhrasing : containerFlow
23+
// @ts-expect-error: `root`s are supposed to have one type of content
24+
return fn(node, state, info)
1925
}

lib/types.js

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,51 +3,46 @@
33
* @typedef {import('unist').Point} Point
44
* @typedef {import('mdast').Root} Root
55
* @typedef {import('mdast').Content} Content
6-
* @typedef {Root | Content} Node
7-
* @typedef {Extract<Node, UnistParent>} Parent
6+
* @typedef {import('mdast').TopLevelContent} TopLevelContent
7+
* @typedef {import('mdast').ListContent} ListContent
8+
* @typedef {import('mdast').PhrasingContent} PhrasingContent
89
*/
910

1011
/**
12+
* @typedef {Root | Content} Node
13+
* @typedef {Extract<Node, UnistParent>} Parent
14+
* @typedef {TopLevelContent | ListContent} FlowContent
15+
*
1116
* @typedef TrackFields
1217
* Info on where we are in the document we are generating.
1318
* @property {Point} now
1419
* Current point.
1520
* @property {number} lineShift
1621
* Number of columns each line will be shifted by wrapping nodes.
17-
*/
18-
19-
/**
22+
*
2023
* @typedef SafeFields
2124
* Info on the characters that are around the current thing we are
2225
* generating.
2326
* @property {string} before
2427
* Characters before this (guaranteed to be one, can be more).
2528
* @property {string} after
2629
* Characters after this (guaranteed to be one, can be more).
27-
*/
28-
29-
/**
30+
*
3031
* @typedef {TrackFields & SafeFields} Info
3132
* Info on the surrounding of the node that is serialized.
32-
*/
33-
34-
/**
33+
*
3534
* @callback Enter
3635
* Enter something.
3736
* @param {string} type
3837
* Label, more similar to a micromark event than an mdast node type.
3938
* @returns {Exit}
4039
* Revert.
41-
*/
42-
43-
/**
40+
*
4441
* @callback Exit
4542
* Exit something.
4643
* @returns {void}
4744
* Nothing.
48-
*/
49-
50-
/**
45+
*
5146
* @typedef State
5247
* Info passed around about the current state.
5348
* @property {Array<string>} stack
@@ -70,9 +65,7 @@
7065
* List marker currently in use.
7166
* @property {string | undefined} bulletLastUsed
7267
* List marker previously in use.
73-
*/
74-
75-
/**
68+
*
7669
* @callback Handle
7770
* Handle a particular node.
7871
* @param {any} node
@@ -85,16 +78,12 @@
8578
* Info on the surrounding of the node that is serialized.
8679
* @returns {string}
8780
* Serialized markdown representing `node`.
88-
*/
89-
90-
/**
81+
*
9182
* @typedef {Record<string, Handle>} Handlers
9283
* Handle particular nodes.
9384
*
9485
* Each key is a node type, each value its corresponding handler.
95-
*/
96-
97-
/**
86+
*
9887
* @callback Join
9988
* How to join two blocks.
10089
*
@@ -131,9 +120,7 @@
131120
* > One such example is when returning `0` for two paragraphs, which will
132121
* > result in the text running together, and in the future to be seen as
133122
* > one paragraph.
134-
*/
135-
136-
/**
123+
*
137124
* @typedef Unsafe
138125
* Schema that defines when a character cannot occur.
139126
* @property {string} character
@@ -153,9 +140,7 @@
153140
* The unsafe pattern (this whole object) compiled as a regex.
154141
*
155142
* This is internal and must not be defined.
156-
*/
157-
158-
/**
143+
*
159144
* @typedef Options
160145
* Configuration (optional).
161146
* @property {'-' | '*' | '+' | null | undefined} [bullet='*']

lib/util/container-flow.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/**
2+
* @typedef {import('../types.js').FlowContent} FlowContent
23
* @typedef {import('../types.js').Node} Node
34
* @typedef {import('../types.js').Parent} Parent
45
* @typedef {import('../types.js').State} State
@@ -8,7 +9,7 @@
89
import {track} from './track.js'
910

1011
/**
11-
* @param {Parent} parent
12+
* @param {Parent & {children: Array<FlowContent>}} parent
1213
* @param {State} state
1314
* @param {TrackFields} info
1415
* @returns {string}

lib/util/container-phrasing.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/**
2+
* @typedef {import('../types.js').PhrasingContent} PhrasingContent
23
* @typedef {import('../types.js').Parent} Parent
34
* @typedef {import('../types.js').Info} Info
45
* @typedef {import('../types.js').Handle} Handle
@@ -8,7 +9,7 @@
89
import {track} from './track.js'
910

1011
/**
11-
* @param {Parent} parent
12+
* @param {Parent & {children: Array<PhrasingContent>}} parent
1213
* @param {State} state
1314
* @param {Info} info
1415
* @returns {string}

lib/util/indent-lines.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export function indentLines(value, map) {
1818
const result = []
1919
let start = 0
2020
let line = 0
21-
/** @type {RegExpExecArray|null} */
21+
/** @type {RegExpExecArray | null} */
2222
let match
2323

2424
while ((match = eol.exec(value))) {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"@types/mdast": "^3.0.0",
4242
"@types/unist": "^2.0.0",
4343
"longest-streak": "^3.0.0",
44+
"mdast-util-phrasing": "^3.0.0",
4445
"mdast-util-to-string": "^3.0.0",
4546
"micromark-util-decode-string": "^1.0.0",
4647
"unist-util-visit": "^4.0.0",

test/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ test('core', () => {
2323
'should support a `root`'
2424
)
2525

26+
assert.equal(
27+
to({
28+
type: 'root',
29+
children: [
30+
{type: 'text', value: 'a'},
31+
{type: 'break'},
32+
{type: 'text', value: 'b'}
33+
]
34+
}),
35+
'a\\\nb\n',
36+
'should not use blank lines between nodes when given phrasing'
37+
)
38+
2639
assert.equal(
2740
to({
2841
type: 'root',

0 commit comments

Comments
 (0)