Skip to content

Commit

Permalink
Add createTracker helper on state
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Jan 4, 2023
1 parent e9f71aa commit 35ceafc
Show file tree
Hide file tree
Showing 18 changed files with 100 additions and 47 deletions.
2 changes: 2 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,9 @@ export type {
Join,
Map,
Options,
SafeConfig,
State,
Tracker,
Unsafe
} from './lib/types.js'
// Deprecated.
Expand Down
4 changes: 1 addition & 3 deletions lib/handle/blockquote.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
* @typedef {import('../types.js').Map} Map
*/

import {track} from '../util/track.js'

/**
* @param {Blockquote} node
* @param {Parent | undefined} _
Expand All @@ -17,7 +15,7 @@ import {track} from '../util/track.js'
*/
export function blockquote(node, _, state, info) {
const exit = state.enter('blockquote')
const tracker = track(info)
const tracker = state.createTracker(info)
tracker.move('> ')
tracker.shift(2)
const value = state.indentLines(
Expand Down
3 changes: 1 addition & 2 deletions lib/handle/code.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import {longestStreak} from 'longest-streak'
import {formatCodeAsIndented} from '../util/format-code-as-indented.js'
import {checkFence} from '../util/check-fence.js'
import {track} from '../util/track.js'

/**
* @param {Code} node
Expand All @@ -30,7 +29,7 @@ export function code(node, _, state, info) {
return value
}

const tracker = track(info)
const tracker = state.createTracker(info)
const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3))
const exit = state.enter('codeFenced')
let value = tracker.move(sequence)
Expand Down
3 changes: 1 addition & 2 deletions lib/handle/definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import {association} from '../util/association.js'
import {checkQuote} from '../util/check-quote.js'
import {track} from '../util/track.js'

/**
* @param {Definition} node
Expand All @@ -21,7 +20,7 @@ export function definition(node, _, state, info) {
const suffix = quote === '"' ? 'Quote' : 'Apostrophe'
const exit = state.enter('definition')
let subexit = state.enter('label')
const tracker = track(info)
const tracker = state.createTracker(info)
let value = tracker.move('[')
value += tracker.move(
state.safe(association(node), {
Expand Down
3 changes: 1 addition & 2 deletions lib/handle/emphasis.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

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

emphasis.peek = emphasisPeek

Expand All @@ -24,7 +23,7 @@ emphasis.peek = emphasisPeek
export function emphasis(node, _, state, info) {
const marker = checkEmphasis(state)
const exit = state.enter('emphasis')
const tracker = track(info)
const tracker = state.createTracker(info)
let value = tracker.move(marker)
value += tracker.move(
state.containerPhrasing(node, {
Expand Down
3 changes: 1 addition & 2 deletions lib/handle/heading.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

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

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

if (formatHeadingAsSetext(node, state)) {
const exit = state.enter('headingSetext')
Expand Down
3 changes: 1 addition & 2 deletions lib/handle/image-reference.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

import {association} from '../util/association.js'
import {track} from '../util/track.js'

imageReference.peek = imageReferencePeek

Expand All @@ -21,7 +20,7 @@ export function imageReference(node, _, state, info) {
const type = node.referenceType
const exit = state.enter('imageReference')
let subexit = state.enter('label')
const tracker = track(info)
const tracker = state.createTracker(info)
let value = tracker.move('![')
const alt = state.safe(node.alt, {
before: value,
Expand Down
3 changes: 1 addition & 2 deletions lib/handle/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

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

image.peek = imagePeek

Expand All @@ -22,7 +21,7 @@ export function image(node, _, state, info) {
const suffix = quote === '"' ? 'Quote' : 'Apostrophe'
const exit = state.enter('image')
let subexit = state.enter('label')
const tracker = track(info)
const tracker = state.createTracker(info)
let value = tracker.move('![')
value += tracker.move(
state.safe(node.alt, {before: value, after: ']', ...tracker.current()})
Expand Down
3 changes: 1 addition & 2 deletions lib/handle/link-reference.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

import {association} from '../util/association.js'
import {track} from '../util/track.js'

linkReference.peek = linkReferencePeek

Expand All @@ -21,7 +20,7 @@ export function linkReference(node, _, state, info) {
const type = node.referenceType
const exit = state.enter('linkReference')
let subexit = state.enter('label')
const tracker = track(info)
const tracker = state.createTracker(info)
let value = tracker.move('[')
const text = state.containerPhrasing(node, {
before: value,
Expand Down
3 changes: 1 addition & 2 deletions lib/handle/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

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

link.peek = linkPeek

Expand All @@ -22,7 +21,7 @@ link.peek = linkPeek
export function link(node, _, state, info) {
const quote = checkQuote(state)
const suffix = quote === '"' ? 'Quote' : 'Apostrophe'
const tracker = track(info)
const tracker = state.createTracker(info)
/** @type {Exit} */
let exit
/** @type {Exit} */
Expand Down
3 changes: 1 addition & 2 deletions lib/handle/list-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

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

/**
* @param {ListItem} node
Expand Down Expand Up @@ -43,7 +42,7 @@ export function listItem(node, parent, state, info) {
size = Math.ceil(size / 4) * 4
}

const tracker = track(info)
const tracker = state.createTracker(info)
tracker.move(bullet + ' '.repeat(size - bullet.length))
tracker.shift(size)
const exit = state.enter('listItem')
Expand Down
3 changes: 1 addition & 2 deletions lib/handle/strong.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

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

strong.peek = strongPeek

Expand All @@ -24,7 +23,7 @@ strong.peek = strongPeek
export function strong(node, _, state, info) {
const marker = checkStrong(state)
const exit = state.enter('strong')
const tracker = track(info)
const tracker = state.createTracker(info)
let value = tracker.move(marker + marker)
value += tracker.move(
state.containerPhrasing(node, {
Expand Down
2 changes: 2 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {containerPhrasing} from './util/container-phrasing.js'
import {containerFlow} from './util/container-flow.js'
import {indentLines} from './util/indent-lines.js'
import {safe} from './util/safe.js'
import {track} from './util/track.js'

/**
* Turn an mdast syntax tree into markdown.
Expand All @@ -39,6 +40,7 @@ export function toMarkdown(tree, options = {}) {
indentLines,
containerPhrasing: containerPhrasingBound,
containerFlow: containerFlowBound,
createTracker: track,
safe: safeBound,
stack: [],
unsafe: [],
Expand Down
43 changes: 43 additions & 0 deletions lib/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,47 @@
* @typedef {TrackFields & SafeFields} Info
* Info on the surrounding of the node that is serialized.
*
* @callback TrackCurrent
* Get current tracked info.
* @returns {TrackFields}
* Current tracked info.
*
* @callback TrackShift
* Define a relative increased line shift (the typical indent for lines).
* @param {number} value
* Relative increment in how much each line will be padded.
* @returns {void}
* Nothing.
*
* @callback TrackMove
* Move past some generated markdown.
* @param {string | null | undefined} value
* Generated markdown.
* @returns {string}
* Given markdown.
*
* @typedef Tracker
* Track positional info in the output.
*
* This info isn’t used yet but such functionality will allow line wrapping,
* source maps, etc.
* @property {TrackCurrent} current
* Get the current tracked info.
* @property {TrackShift} shift
* Define an increased line shift (the typical indent for lines).
* @property {TrackMove} move
* Move past some generated markdown.
*
* @callback CreateTracker
* Track positional info in the output.
*
* This info isn’t used yet but such functionality will allow line wrapping,
* source maps, etc.
* @param {TrackFields} info
* Info on where we are in the document we are generating.
* @returns {Tracker}
* Tracker.
*
* @callback Map
* Map function to pad a single line.
* @param {string} value
Expand Down Expand Up @@ -132,6 +173,8 @@
* Serialize the children of a parent that contains phrasing children.
* @property {ContainerFlow} containerFlow
* Serialize the children of a parent that contains flow children.
* @property {CreateTracker} createTracker
* Track positional info in the output.
* @property {Safe} safe
* Serialize the children of a parent that contains flow children.
* @property {Enter} enter
Expand Down
4 changes: 1 addition & 3 deletions lib/util/container-flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
* @typedef {import('../types.js').TrackFields} TrackFields
*/

import {track} from './track.js'

/**
* @param {Parent & {children: Array<FlowContent>}} parent
* Parent of flow nodes.
Expand All @@ -21,7 +19,7 @@ import {track} from './track.js'
export function containerFlow(parent, state, info) {
const indexStack = state.indexStack
const children = parent.children || []
const tracker = track(info)
const tracker = state.createTracker(info)
/** @type {Array<string>} */
const results = []
let index = -1
Expand Down
6 changes: 2 additions & 4 deletions lib/util/container-phrasing.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
* @typedef {import('../types.js').State} State
*/

import {track} from './track.js'

/**
* Serialize the children of a parent that contains phrasing children.
*
Expand All @@ -31,7 +29,7 @@ export function containerPhrasing(parent, state, info) {
let before = info.before

indexStack.push(-1)
let tracker = track(info)
let tracker = state.createTracker(info)

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

// To do: does this work to reset tracker?
tracker = track(info)
tracker = state.createTracker(info)
tracker.move(results.join(''))
}

Expand Down
30 changes: 15 additions & 15 deletions lib/util/track.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
/**
* @typedef {import('unist').Point} Point
* @typedef {import('../types.js').TrackFields} TrackFields
* @typedef {import('../types.js').CreateTracker} CreateTracker
* @typedef {import('../types.js').TrackCurrent} TrackCurrent
* @typedef {import('../types.js').TrackMove} TrackMove
* @typedef {import('../types.js').TrackShift} TrackShift
*/

/**
* Functions to track output positions.
* Track positional info in the output.
*
* This info isn’t used yet but suchs functionality allows line wrapping,
* and theoretically source maps (though, is there practical use in that?).
*
* @param {TrackFields} options_
* @type {CreateTracker}
*/
export function track(options_) {
export function track(config) {
// Defaults are used to prevent crashes when older utilities somehow activate
// this code.
/* c8 ignore next 5 */
const options = options_ || {}
const options = config || {}
const now = options.now || {}
let lineShift = options.lineShift || 0
let line = now.line || 1
Expand All @@ -26,7 +25,7 @@ export function track(options_) {
/**
* Get the current tracked info.
*
* @returns {TrackFields}
* @type {TrackCurrent}
*/
function current() {
return {now: {line, column}, lineShift}
Expand All @@ -35,19 +34,20 @@ export function track(options_) {
/**
* Define an increased line shift (the typical indent for lines).
*
* @param {number} value
* @type {TrackShift}
*/
function shift(value) {
lineShift += value
}

/**
* Move past a string.
* Move past some generated markdown.
*
* @param {string} value
* @returns {string}
* @type {TrackMove}
*/
function move(value = '') {
function move(input) {
// eslint-disable-next-line unicorn/prefer-default-parameters
const value = input || ''
const chunks = value.split(/\r?\n|\r/g)
const tail = chunks[chunks.length - 1]
line += chunks.length - 1
Expand Down

0 comments on commit 35ceafc

Please sign in to comment.