Skip to content

Commit f0e0c1c

Browse files
committed
Change exports to functions that return extensions
Previously the `mathFromMarkdown` and `mathToMarkdown` exports were extensions themselves. Now they are functions that returns such extensions. Related-to: remarkjs/remark-math#63.
1 parent 9984e05 commit f0e0c1c

File tree

3 files changed

+191
-177
lines changed

3 files changed

+191
-177
lines changed

Diff for: index.js

+163-149
Original file line numberDiff line numberDiff line change
@@ -10,173 +10,187 @@
1010
import {longestStreak} from 'longest-streak'
1111
import {safe} from 'mdast-util-to-markdown/lib/util/safe.js'
1212

13-
/** @type {FromMarkdownExtension} */
14-
export const mathFromMarkdown = {
15-
enter: {
16-
mathFlow: enterMathFlow,
17-
mathFlowFenceMeta: enterMathFlowMeta,
18-
mathText: enterMathText
19-
},
20-
exit: {
21-
mathFlow: exitMathFlow,
22-
mathFlowFence: exitMathFlowFence,
23-
mathFlowFenceMeta: exitMathFlowMeta,
24-
mathFlowValue: exitMathData,
25-
mathText: exitMathText,
26-
mathTextData: exitMathData
27-
}
28-
}
29-
30-
/** @type {ToMarkdownExtension} */
31-
export const mathToMarkdown = {
32-
unsafe: [
33-
{character: '\r', inConstruct: ['mathFlowMeta']},
34-
{character: '\r', inConstruct: ['mathFlowMeta']},
35-
{character: '$', inConstruct: ['mathFlowMeta', 'phrasing']},
36-
{atBreak: true, character: '$', after: '\\$'}
37-
],
38-
handlers: {math, inlineMath}
39-
}
40-
41-
inlineMath.peek = inlineMathPeek
42-
43-
/** @type {FromMarkdownHandle} */
44-
function enterMathFlow(token) {
45-
this.enter(
46-
{
47-
type: 'math',
48-
meta: null,
49-
value: '',
50-
data: {
51-
hName: 'div',
52-
hProperties: {className: ['math', 'math-display']},
53-
hChildren: [{type: 'text', value: ''}]
54-
}
13+
/**
14+
* @returns {FromMarkdownExtension}
15+
*/
16+
export function mathFromMarkdown() {
17+
return {
18+
enter: {
19+
mathFlow: enterMathFlow,
20+
mathFlowFenceMeta: enterMathFlowMeta,
21+
mathText: enterMathText
5522
},
56-
token
57-
)
58-
}
59-
60-
/** @type {FromMarkdownHandle} */
61-
function enterMathFlowMeta() {
62-
this.buffer()
63-
}
64-
65-
/** @type {FromMarkdownHandle} */
66-
function exitMathFlowMeta() {
67-
const data = this.resume()
68-
const node = /** @type {Math} */ (this.stack[this.stack.length - 1])
69-
node.meta = data
70-
}
71-
72-
/** @type {FromMarkdownHandle} */
73-
function exitMathFlowFence() {
74-
// Exit if this is the closing fence.
75-
if (this.getData('mathFlowInside')) return
76-
this.buffer()
77-
this.setData('mathFlowInside', true)
78-
}
23+
exit: {
24+
mathFlow: exitMathFlow,
25+
mathFlowFence: exitMathFlowFence,
26+
mathFlowFenceMeta: exitMathFlowMeta,
27+
mathFlowValue: exitMathData,
28+
mathText: exitMathText,
29+
mathTextData: exitMathData
30+
}
31+
}
7932

80-
/** @type {FromMarkdownHandle} */
81-
function exitMathFlow(token) {
82-
const data = this.resume().replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '')
83-
const node = /** @type {Math} */ (this.exit(token))
84-
node.value = data
85-
// @ts-expect-error: we defined it.
86-
node.data.hChildren[0].value = data
87-
this.setData('mathFlowInside')
88-
}
33+
/** @type {FromMarkdownHandle} */
34+
function enterMathFlow(token) {
35+
this.enter(
36+
{
37+
type: 'math',
38+
meta: null,
39+
value: '',
40+
data: {
41+
hName: 'div',
42+
hProperties: {className: ['math', 'math-display']},
43+
hChildren: [{type: 'text', value: ''}]
44+
}
45+
},
46+
token
47+
)
48+
}
8949

90-
/** @type {FromMarkdownHandle} */
91-
function enterMathText(token) {
92-
this.enter(
93-
{
94-
type: 'inlineMath',
95-
value: '',
96-
data: {
97-
hName: 'span',
98-
hProperties: {className: ['math', 'math-inline']},
99-
hChildren: [{type: 'text', value: ''}]
100-
}
101-
},
102-
token
103-
)
104-
this.buffer()
105-
}
50+
/** @type {FromMarkdownHandle} */
51+
function enterMathFlowMeta() {
52+
this.buffer()
53+
}
10654

107-
/** @type {FromMarkdownHandle} */
108-
function exitMathText(token) {
109-
const data = this.resume()
110-
const node = /** @type {Math} */ (this.exit(token))
111-
node.value = data
112-
// @ts-expect-error: we defined it.
113-
node.data.hChildren[0].value = data
114-
}
55+
/** @type {FromMarkdownHandle} */
56+
function exitMathFlowMeta() {
57+
const data = this.resume()
58+
const node = /** @type {Math} */ (this.stack[this.stack.length - 1])
59+
node.meta = data
60+
}
11561

116-
/** @type {FromMarkdownHandle} */
117-
function exitMathData(token) {
118-
this.config.enter.data.call(this, token)
119-
this.config.exit.data.call(this, token)
120-
}
62+
/** @type {FromMarkdownHandle} */
63+
function exitMathFlowFence() {
64+
// Exit if this is the closing fence.
65+
if (this.getData('mathFlowInside')) return
66+
this.buffer()
67+
this.setData('mathFlowInside', true)
68+
}
12169

122-
/**
123-
* @type {ToMarkdownHandle}
124-
* @param {Math} node
125-
*/
126-
function math(node, _, context) {
127-
const raw = node.value || ''
128-
const fence = '$'.repeat(Math.max(longestStreak(raw, '$') + 1, 2))
129-
const exit = context.enter('mathFlow')
130-
let value = fence
131-
132-
if (node.meta) {
133-
const subexit = context.enter('mathFlowMeta')
134-
value += safe(context, node.meta, {before: '$', after: ' ', encode: ['$']})
135-
subexit()
70+
/** @type {FromMarkdownHandle} */
71+
function exitMathFlow(token) {
72+
const data = this.resume().replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '')
73+
const node = /** @type {Math} */ (this.exit(token))
74+
node.value = data
75+
// @ts-expect-error: we defined it.
76+
node.data.hChildren[0].value = data
77+
this.setData('mathFlowInside')
13678
}
13779

138-
value += '\n'
80+
/** @type {FromMarkdownHandle} */
81+
function enterMathText(token) {
82+
this.enter(
83+
{
84+
type: 'inlineMath',
85+
value: '',
86+
data: {
87+
hName: 'span',
88+
hProperties: {className: ['math', 'math-inline']},
89+
hChildren: [{type: 'text', value: ''}]
90+
}
91+
},
92+
token
93+
)
94+
this.buffer()
95+
}
13996

140-
if (raw) {
141-
value += raw + '\n'
97+
/** @type {FromMarkdownHandle} */
98+
function exitMathText(token) {
99+
const data = this.resume()
100+
const node = /** @type {Math} */ (this.exit(token))
101+
node.value = data
102+
// @ts-expect-error: we defined it.
103+
node.data.hChildren[0].value = data
142104
}
143105

144-
value += fence
145-
exit()
146-
return value
106+
/** @type {FromMarkdownHandle} */
107+
function exitMathData(token) {
108+
this.config.enter.data.call(this, token)
109+
this.config.exit.data.call(this, token)
110+
}
147111
}
148112

149113
/**
150-
* @type {ToMarkdownHandle}
151-
* @param {InlineMath} node
114+
* @returns {ToMarkdownExtension}
152115
*/
153-
function inlineMath(node) {
154-
const value = node.value || ''
155-
let size = 1
156-
let pad = ''
157-
158-
// If there is a single dollar sign on its own in the math, use a fence of
159-
// two.
160-
// If there are two in a row, use one.
161-
while (new RegExp('(^|[^$])' + '\\$'.repeat(size) + '([^$]|$)').test(value)) {
162-
size++
116+
export function mathToMarkdown() {
117+
inlineMath.peek = inlineMathPeek
118+
119+
return {
120+
unsafe: [
121+
{character: '\r', inConstruct: ['mathFlowMeta']},
122+
{character: '\r', inConstruct: ['mathFlowMeta']},
123+
{character: '$', inConstruct: ['mathFlowMeta', 'phrasing']},
124+
{atBreak: true, character: '$', after: '\\$'}
125+
],
126+
handlers: {math, inlineMath}
163127
}
164128

165-
// If this is not just spaces or eols (tabs don’t count), and either the first
166-
// or last character are a space, eol, or dollar sign, then pad with spaces.
167-
if (
168-
/[^ \r\n]/.test(value) &&
169-
(/[ \r\n$]/.test(value.charAt(0)) ||
170-
/[ \r\n$]/.test(value.charAt(value.length - 1)))
171-
) {
172-
pad = ' '
129+
/**
130+
* @type {ToMarkdownHandle}
131+
* @param {Math} node
132+
*/
133+
function math(node, _, context) {
134+
const raw = node.value || ''
135+
const fence = '$'.repeat(Math.max(longestStreak(raw, '$') + 1, 2))
136+
const exit = context.enter('mathFlow')
137+
let value = fence
138+
139+
if (node.meta) {
140+
const subexit = context.enter('mathFlowMeta')
141+
value += safe(context, node.meta, {
142+
before: '$',
143+
after: ' ',
144+
encode: ['$']
145+
})
146+
subexit()
147+
}
148+
149+
value += '\n'
150+
151+
if (raw) {
152+
value += raw + '\n'
153+
}
154+
155+
value += fence
156+
exit()
157+
return value
173158
}
174159

175-
const sequence = '$'.repeat(size)
176-
return sequence + pad + value + pad + sequence
177-
}
160+
/**
161+
* @type {ToMarkdownHandle}
162+
* @param {InlineMath} node
163+
*/
164+
function inlineMath(node) {
165+
const value = node.value || ''
166+
let size = 1
167+
let pad = ''
168+
169+
// If there is a single dollar sign on its own in the math, use a fence of
170+
// two.
171+
// If there are two in a row, use one.
172+
while (
173+
new RegExp('(^|[^$])' + '\\$'.repeat(size) + '([^$]|$)').test(value)
174+
) {
175+
size++
176+
}
177+
178+
// If this is not just spaces or eols (tabs don’t count), and either the first
179+
// or last character are a space, eol, or dollar sign, then pad with spaces.
180+
if (
181+
/[^ \r\n]/.test(value) &&
182+
(/[ \r\n$]/.test(value.charAt(0)) ||
183+
/[ \r\n$]/.test(value.charAt(value.length - 1)))
184+
) {
185+
pad = ' '
186+
}
187+
188+
const sequence = '$'.repeat(size)
189+
return sequence + pad + value + pad + sequence
190+
}
178191

179-
/** @type {ToMarkdownHandle} */
180-
function inlineMathPeek() {
181-
return '$'
192+
/** @type {ToMarkdownHandle} */
193+
function inlineMathPeek() {
194+
return '$'
195+
}
182196
}

Diff for: readme.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ L = \frac{1}{2} \rho v^2 S C_L
4343
$$
4444
```
4545

46-
And our script, `example.js`, looks as follows:
46+
And our module, `example.js`, looks as follows:
4747

4848
```js
49-
import fs from 'fs'
49+
import fs from 'node:fs'
5050
import {fromMarkdown} from 'mdast-util-from-markdown'
5151
import {toMarkdown} from 'mdast-util-to-markdown'
5252
import {math} from 'micromark-extension-math'
@@ -55,13 +55,13 @@ import {mathFromMarkdown, mathToMarkdown} from 'mdast-util-math'
5555
const doc = fs.readFileSync('example.md')
5656

5757
const tree = fromMarkdown(doc, {
58-
extensions: [math],
59-
mdastExtensions: [mathFromMarkdown]
58+
extensions: [math()],
59+
mdastExtensions: [mathFromMarkdown()]
6060
})
6161

6262
console.log(tree)
6363

64-
const out = toMarkdown(tree, {extensions: [mathToMarkdown]})
64+
const out = toMarkdown(tree, {extensions: [mathToMarkdown()]})
6565

6666
console.log(out)
6767
```
@@ -97,16 +97,16 @@ $$
9797

9898
## API
9999

100-
This package exports the following identifier: `mathFromMarkdown`,
100+
This package exports the following identifiers: `mathFromMarkdown`,
101101
`mathToMarkdown`.
102102
There is no default export.
103103

104-
### `mathFromMarkdown`
104+
### `mathFromMarkdown()`
105105

106-
### `mathToMarkdown`
106+
### `mathToMarkdown()`
107107

108108
Support math.
109-
These exports are extensions, respectively for
109+
These exports are functions that create extensions, respectively for
110110
[`mdast-util-from-markdown`][from-markdown] and
111111
[`mdast-util-to-markdown`][to-markdown].
112112

0 commit comments

Comments
 (0)