Skip to content

Commit 35ceafc

Browse files
committed
Add createTracker helper on state
1 parent e9f71aa commit 35ceafc

18 files changed

+100
-47
lines changed

index.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,9 @@ export type {
316316
Join,
317317
Map,
318318
Options,
319+
SafeConfig,
319320
State,
321+
Tracker,
320322
Unsafe
321323
} from './lib/types.js'
322324
// Deprecated.

lib/handle/blockquote.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
* @typedef {import('../types.js').Map} Map
77
*/
88

9-
import {track} from '../util/track.js'
10-
119
/**
1210
* @param {Blockquote} node
1311
* @param {Parent | undefined} _
@@ -17,7 +15,7 @@ import {track} from '../util/track.js'
1715
*/
1816
export function blockquote(node, _, state, info) {
1917
const exit = state.enter('blockquote')
20-
const tracker = track(info)
18+
const tracker = state.createTracker(info)
2119
tracker.move('> ')
2220
tracker.shift(2)
2321
const value = state.indentLines(

lib/handle/code.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import {longestStreak} from 'longest-streak'
1010
import {formatCodeAsIndented} from '../util/format-code-as-indented.js'
1111
import {checkFence} from '../util/check-fence.js'
12-
import {track} from '../util/track.js'
1312

1413
/**
1514
* @param {Code} node
@@ -30,7 +29,7 @@ export function code(node, _, state, info) {
3029
return value
3130
}
3231

33-
const tracker = track(info)
32+
const tracker = state.createTracker(info)
3433
const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3))
3534
const exit = state.enter('codeFenced')
3635
let value = tracker.move(sequence)

lib/handle/definition.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import {association} from '../util/association.js'
99
import {checkQuote} from '../util/check-quote.js'
10-
import {track} from '../util/track.js'
1110

1211
/**
1312
* @param {Definition} node
@@ -21,7 +20,7 @@ export function definition(node, _, state, info) {
2120
const suffix = quote === '"' ? 'Quote' : 'Apostrophe'
2221
const exit = state.enter('definition')
2322
let subexit = state.enter('label')
24-
const tracker = track(info)
23+
const tracker = state.createTracker(info)
2524
let value = tracker.move('[')
2625
value += tracker.move(
2726
state.safe(association(node), {

lib/handle/emphasis.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77

88
import {checkEmphasis} from '../util/check-emphasis.js'
9-
import {track} from '../util/track.js'
109

1110
emphasis.peek = emphasisPeek
1211

@@ -24,7 +23,7 @@ emphasis.peek = emphasisPeek
2423
export function emphasis(node, _, state, info) {
2524
const marker = checkEmphasis(state)
2625
const exit = state.enter('emphasis')
27-
const tracker = track(info)
26+
const tracker = state.createTracker(info)
2827
let value = tracker.move(marker)
2928
value += tracker.move(
3029
state.containerPhrasing(node, {

lib/handle/heading.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77

88
import {formatHeadingAsSetext} from '../util/format-heading-as-setext.js'
9-
import {track} from '../util/track.js'
109

1110
/**
1211
* @param {Heading} node
@@ -17,7 +16,7 @@ import {track} from '../util/track.js'
1716
*/
1817
export function heading(node, _, state, info) {
1918
const rank = Math.max(Math.min(6, node.depth || 1), 1)
20-
const tracker = track(info)
19+
const tracker = state.createTracker(info)
2120

2221
if (formatHeadingAsSetext(node, state)) {
2322
const exit = state.enter('headingSetext')

lib/handle/image-reference.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77

88
import {association} from '../util/association.js'
9-
import {track} from '../util/track.js'
109

1110
imageReference.peek = imageReferencePeek
1211

@@ -21,7 +20,7 @@ export function imageReference(node, _, state, info) {
2120
const type = node.referenceType
2221
const exit = state.enter('imageReference')
2322
let subexit = state.enter('label')
24-
const tracker = track(info)
23+
const tracker = state.createTracker(info)
2524
let value = tracker.move('![')
2625
const alt = state.safe(node.alt, {
2726
before: value,

lib/handle/image.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77

88
import {checkQuote} from '../util/check-quote.js'
9-
import {track} from '../util/track.js'
109

1110
image.peek = imagePeek
1211

@@ -22,7 +21,7 @@ export function image(node, _, state, info) {
2221
const suffix = quote === '"' ? 'Quote' : 'Apostrophe'
2322
const exit = state.enter('image')
2423
let subexit = state.enter('label')
25-
const tracker = track(info)
24+
const tracker = state.createTracker(info)
2625
let value = tracker.move('![')
2726
value += tracker.move(
2827
state.safe(node.alt, {before: value, after: ']', ...tracker.current()})

lib/handle/link-reference.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77

88
import {association} from '../util/association.js'
9-
import {track} from '../util/track.js'
109

1110
linkReference.peek = linkReferencePeek
1211

@@ -21,7 +20,7 @@ export function linkReference(node, _, state, info) {
2120
const type = node.referenceType
2221
const exit = state.enter('linkReference')
2322
let subexit = state.enter('label')
24-
const tracker = track(info)
23+
const tracker = state.createTracker(info)
2524
let value = tracker.move('[')
2625
const text = state.containerPhrasing(node, {
2726
before: value,

lib/handle/link.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import {checkQuote} from '../util/check-quote.js'
1010
import {formatLinkAsAutolink} from '../util/format-link-as-autolink.js'
11-
import {track} from '../util/track.js'
1211

1312
link.peek = linkPeek
1413

@@ -22,7 +21,7 @@ link.peek = linkPeek
2221
export function link(node, _, state, info) {
2322
const quote = checkQuote(state)
2423
const suffix = quote === '"' ? 'Quote' : 'Apostrophe'
25-
const tracker = track(info)
24+
const tracker = state.createTracker(info)
2625
/** @type {Exit} */
2726
let exit
2827
/** @type {Exit} */

lib/handle/list-item.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import {checkBullet} from '../util/check-bullet.js'
1010
import {checkListItemIndent} from '../util/check-list-item-indent.js'
11-
import {track} from '../util/track.js'
1211

1312
/**
1413
* @param {ListItem} node
@@ -43,7 +42,7 @@ export function listItem(node, parent, state, info) {
4342
size = Math.ceil(size / 4) * 4
4443
}
4544

46-
const tracker = track(info)
45+
const tracker = state.createTracker(info)
4746
tracker.move(bullet + ' '.repeat(size - bullet.length))
4847
tracker.shift(size)
4948
const exit = state.enter('listItem')

lib/handle/strong.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
*/
77

88
import {checkStrong} from '../util/check-strong.js'
9-
import {track} from '../util/track.js'
109

1110
strong.peek = strongPeek
1211

@@ -24,7 +23,7 @@ strong.peek = strongPeek
2423
export function strong(node, _, state, info) {
2524
const marker = checkStrong(state)
2625
const exit = state.enter('strong')
27-
const tracker = track(info)
26+
const tracker = state.createTracker(info)
2827
let value = tracker.move(marker + marker)
2928
value += tracker.move(
3029
state.containerPhrasing(node, {

lib/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {containerPhrasing} from './util/container-phrasing.js'
2121
import {containerFlow} from './util/container-flow.js'
2222
import {indentLines} from './util/indent-lines.js'
2323
import {safe} from './util/safe.js'
24+
import {track} from './util/track.js'
2425

2526
/**
2627
* Turn an mdast syntax tree into markdown.
@@ -39,6 +40,7 @@ export function toMarkdown(tree, options = {}) {
3940
indentLines,
4041
containerPhrasing: containerPhrasingBound,
4142
containerFlow: containerFlowBound,
43+
createTracker: track,
4244
safe: safeBound,
4345
stack: [],
4446
unsafe: [],

lib/types.js

+43
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,47 @@
3232
* @typedef {TrackFields & SafeFields} Info
3333
* Info on the surrounding of the node that is serialized.
3434
*
35+
* @callback TrackCurrent
36+
* Get current tracked info.
37+
* @returns {TrackFields}
38+
* Current tracked info.
39+
*
40+
* @callback TrackShift
41+
* Define a relative increased line shift (the typical indent for lines).
42+
* @param {number} value
43+
* Relative increment in how much each line will be padded.
44+
* @returns {void}
45+
* Nothing.
46+
*
47+
* @callback TrackMove
48+
* Move past some generated markdown.
49+
* @param {string | null | undefined} value
50+
* Generated markdown.
51+
* @returns {string}
52+
* Given markdown.
53+
*
54+
* @typedef Tracker
55+
* Track positional info in the output.
56+
*
57+
* This info isn’t used yet but such functionality will allow line wrapping,
58+
* source maps, etc.
59+
* @property {TrackCurrent} current
60+
* Get the current tracked info.
61+
* @property {TrackShift} shift
62+
* Define an increased line shift (the typical indent for lines).
63+
* @property {TrackMove} move
64+
* Move past some generated markdown.
65+
*
66+
* @callback CreateTracker
67+
* Track positional info in the output.
68+
*
69+
* This info isn’t used yet but such functionality will allow line wrapping,
70+
* source maps, etc.
71+
* @param {TrackFields} info
72+
* Info on where we are in the document we are generating.
73+
* @returns {Tracker}
74+
* Tracker.
75+
*
3576
* @callback Map
3677
* Map function to pad a single line.
3778
* @param {string} value
@@ -132,6 +173,8 @@
132173
* Serialize the children of a parent that contains phrasing children.
133174
* @property {ContainerFlow} containerFlow
134175
* Serialize the children of a parent that contains flow children.
176+
* @property {CreateTracker} createTracker
177+
* Track positional info in the output.
135178
* @property {Safe} safe
136179
* Serialize the children of a parent that contains flow children.
137180
* @property {Enter} enter

lib/util/container-flow.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
* @typedef {import('../types.js').TrackFields} TrackFields
77
*/
88

9-
import {track} from './track.js'
10-
119
/**
1210
* @param {Parent & {children: Array<FlowContent>}} parent
1311
* Parent of flow nodes.
@@ -21,7 +19,7 @@ import {track} from './track.js'
2119
export function containerFlow(parent, state, info) {
2220
const indexStack = state.indexStack
2321
const children = parent.children || []
24-
const tracker = track(info)
22+
const tracker = state.createTracker(info)
2523
/** @type {Array<string>} */
2624
const results = []
2725
let index = -1

lib/util/container-phrasing.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
* @typedef {import('../types.js').State} State
77
*/
88

9-
import {track} from './track.js'
10-
119
/**
1210
* Serialize the children of a parent that contains phrasing children.
1311
*
@@ -31,7 +29,7 @@ export function containerPhrasing(parent, state, info) {
3129
let before = info.before
3230

3331
indexStack.push(-1)
34-
let tracker = track(info)
32+
let tracker = state.createTracker(info)
3533

3634
while (++index < children.length) {
3735
const child = children[index]
@@ -76,7 +74,7 @@ export function containerPhrasing(parent, state, info) {
7674
before = ' '
7775

7876
// To do: does this work to reset tracker?
79-
tracker = track(info)
77+
tracker = state.createTracker(info)
8078
tracker.move(results.join(''))
8179
}
8280

lib/util/track.js

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
/**
2-
* @typedef {import('unist').Point} Point
3-
* @typedef {import('../types.js').TrackFields} TrackFields
2+
* @typedef {import('../types.js').CreateTracker} CreateTracker
3+
* @typedef {import('../types.js').TrackCurrent} TrackCurrent
4+
* @typedef {import('../types.js').TrackMove} TrackMove
5+
* @typedef {import('../types.js').TrackShift} TrackShift
46
*/
57

68
/**
7-
* Functions to track output positions.
9+
* Track positional info in the output.
810
*
9-
* This info isn’t used yet but suchs functionality allows line wrapping,
10-
* and theoretically source maps (though, is there practical use in that?).
11-
*
12-
* @param {TrackFields} options_
11+
* @type {CreateTracker}
1312
*/
14-
export function track(options_) {
13+
export function track(config) {
1514
// Defaults are used to prevent crashes when older utilities somehow activate
1615
// this code.
1716
/* c8 ignore next 5 */
18-
const options = options_ || {}
17+
const options = config || {}
1918
const now = options.now || {}
2019
let lineShift = options.lineShift || 0
2120
let line = now.line || 1
@@ -26,7 +25,7 @@ export function track(options_) {
2625
/**
2726
* Get the current tracked info.
2827
*
29-
* @returns {TrackFields}
28+
* @type {TrackCurrent}
3029
*/
3130
function current() {
3231
return {now: {line, column}, lineShift}
@@ -35,19 +34,20 @@ export function track(options_) {
3534
/**
3635
* Define an increased line shift (the typical indent for lines).
3736
*
38-
* @param {number} value
37+
* @type {TrackShift}
3938
*/
4039
function shift(value) {
4140
lineShift += value
4241
}
4342

4443
/**
45-
* Move past a string.
44+
* Move past some generated markdown.
4645
*
47-
* @param {string} value
48-
* @returns {string}
46+
* @type {TrackMove}
4947
*/
50-
function move(value = '') {
48+
function move(input) {
49+
// eslint-disable-next-line unicorn/prefer-default-parameters
50+
const value = input || ''
5151
const chunks = value.split(/\r?\n|\r/g)
5252
const tail = chunks[chunks.length - 1]
5353
line += chunks.length - 1

0 commit comments

Comments
 (0)