From 31360ab610a30ed7d1148645feefe523cdba4879 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Wed, 25 Aug 2021 11:18:45 +0200 Subject: [PATCH] Add `singleDollarTextMath` option This option can be used to prevent math (text) from forming if only one dollar is used. Related-to: remarkjs/remark-math#63. --- index.js | 26 ++++++++++++++++++++++++-- readme.md | 11 ++++++++++- test.js | 27 +++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index ba5f84e..12802f9 100644 --- a/index.js +++ b/index.js @@ -5,6 +5,13 @@ * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle * @typedef {import('./complex-types').Math} Math * @typedef {import('./complex-types').InlineMath} InlineMath + * + * @typedef ToOptions + * @property {boolean} [singleDollarTextMath=true] + * Whether to support math (text) with a single dollar (`boolean`, default: + * `true`). + * Single dollars work in Pandoc and many other places, but often interfere + * with “normal” dollars in text. */ import {longestStreak} from 'longest-streak' @@ -111,16 +118,29 @@ export function mathFromMarkdown() { } /** + * @param {ToOptions} [options] * @returns {ToMarkdownExtension} */ -export function mathToMarkdown() { +export function mathToMarkdown(options = {}) { + let single = options.singleDollarTextMath + + if (single === null || single === undefined) { + single = true + } + inlineMath.peek = inlineMathPeek return { unsafe: [ {character: '\r', inConstruct: ['mathFlowMeta']}, {character: '\r', inConstruct: ['mathFlowMeta']}, - {character: '$', inConstruct: ['mathFlowMeta', 'phrasing']}, + single + ? {character: '$', inConstruct: ['mathFlowMeta', 'phrasing']} + : { + character: '$', + after: '\\$', + inConstruct: ['mathFlowMeta', 'phrasing'] + }, {atBreak: true, character: '$', after: '\\$'} ], handlers: {math, inlineMath} @@ -166,6 +186,8 @@ export function mathToMarkdown() { let size = 1 let pad = '' + if (!single) size++ + // If there is a single dollar sign on its own in the math, use a fence of // two. // If there are two in a row, use one. diff --git a/readme.md b/readme.md index 770bb99..617f930 100644 --- a/readme.md +++ b/readme.md @@ -103,13 +103,22 @@ There is no default export. ### `mathFromMarkdown()` -### `mathToMarkdown()` +### `mathToMarkdown(toOptions?)` Support math. These exports are functions that create extensions, respectively for [`mdast-util-from-markdown`][from-markdown] and [`mdast-util-to-markdown`][to-markdown]. +##### `toOptions` + +###### `toOptions.singleDollarTextMath` + +Whether to support math (text) with a single dollar (`boolean`, default: +`true`). +Single dollars work in Pandoc and many other places, but often interfere with +“normal” dollars in text. + ## Related * [`remarkjs/remark`][remark] diff --git a/test.js b/test.js index 35b6166..0a8b52f 100644 --- a/test.js +++ b/test.js @@ -147,6 +147,15 @@ test('mdast -> markdown', (t) => { 'should serialize math (text)' ) + t.deepEqual( + toMarkdown( + {type: 'inlineMath', value: 'a'}, + {extensions: [mathToMarkdown({singleDollarTextMath: false})]} + ), + '$$a$$\n', + 'should serialize math (text) with at least 2 dollars w/ `singleDollarTextMath: false`' + ) + t.deepEqual( // @ts-expect-error: `value` missing. toMarkdown({type: 'inlineMath'}, {extensions: [mathToMarkdown()]}), @@ -223,6 +232,24 @@ test('mdast -> markdown', (t) => { 'should escape `$` in phrasing' ) + t.deepEqual( + toMarkdown( + {type: 'paragraph', children: [{type: 'text', value: 'a $ b'}]}, + {extensions: [mathToMarkdown({singleDollarTextMath: false})]} + ), + 'a $ b\n', + 'should not escape a single dollar in phrasing w/ `singleDollarTextMath: false`' + ) + + t.deepEqual( + toMarkdown( + {type: 'paragraph', children: [{type: 'text', value: 'a $$ b'}]}, + {extensions: [mathToMarkdown({singleDollarTextMath: false})]} + ), + 'a \\$$ b\n', + 'should escape two dollars in phrasing w/ `singleDollarTextMath: false`' + ) + t.deepEqual( toMarkdown( {