Skip to content

Commit

Permalink
Merge pull request #1002 from pjkaufman/master
Browse files Browse the repository at this point in the history
Fixed Content on Same Line as Math Block Indicator Getting Put At Start of Each Line Outside of a Blockquote for Inline Math for Moving Math Indicators to Their Own Lines
  • Loading branch information
pjkaufman authored Jan 27, 2024
2 parents 5ed5733 + 059e38e commit 4cd434c
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 10 deletions.
36 changes: 36 additions & 0 deletions __tests__/move-math-block-indicators-to-own-line.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,41 @@ ruleTest({
text
`,
},
{ // accounts for https://github.com/platers/obsidian-linter/issues/996
testName: 'Math indicators with content before them should not have that content duplicated unless it is a blockquote',
before: dedent`
a $$b$$
`,
after: dedent`
a
$$
b
$$
`,
},
{ // relates to https://github.com/platers/obsidian-linter/issues/996
testName: 'Math indicators with content before them should have the opening indicator moved to a new line and have any tabs and spaces that were between the content and the opening indicators removed.',
before: dedent`
a \t $$b$$
`,
after: dedent`
a
$$
b
$$
`,
},
{ // relates to https://github.com/platers/obsidian-linter/issues/996
testName: 'Math indicators in a blockquote/callout with content before them should have the opening indicator moved to a new line and have any tabs and spaces that were between the content and the opening indicators removed.',
before: dedent`
> a \t $$b$$
`,
after: dedent`
> a
> $$
> b
> $$
`,
},
],
});
46 changes: 36 additions & 10 deletions src/utils/mdast.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {visit} from 'unist-util-visit';
import type {Position} from 'unist';
import type {Root} from 'mdast';
import {hashString53Bit, makeSureContentHasEmptyLinesAddedBeforeAndAfter, replaceTextBetweenStartAndEndWithNewValue, getStartOfLineIndex, replaceAt} from './strings';
import {genericLinkRegex, tableRow, tableSeparator, tableStartingPipe, customIgnoreAllStartIndicator, customIgnoreAllEndIndicator, checklistBoxStartsTextRegex, footnoteDefinitionIndicatorAtStartOfLine} from './regex';
import {hashString53Bit, makeSureContentHasEmptyLinesAddedBeforeAndAfter, replaceTextBetweenStartAndEndWithNewValue, getStartOfLineIndex, replaceAt, getStartOfLineWhitespaceOrBlockquoteLevel} from './strings';
import {genericLinkRegex, tableRow, tableSeparator, tableStartingPipe, customIgnoreAllStartIndicator, customIgnoreAllEndIndicator, checklistBoxStartsTextRegex, footnoteDefinitionIndicatorAtStartOfLine, emptyLineMathBlockquoteRegex, startsWithBlockquote} from './regex';
import {gfmFootnote} from 'micromark-extension-gfm-footnote';
import {gfmTaskListItem} from 'micromark-extension-gfm-task-list-item';
import {combineExtensions} from 'micromark-util-combine-extensions';
Expand Down Expand Up @@ -830,30 +830,56 @@ function breakMathBlockIntoMultipleBlocksIfNeedBe(mathBlock: string, numberOfDol

function addBlankLinesAroundStartAndStopMathIndicators(text: string, mathBlockStartIndex: number, mathBlockEndIndex: number, mathOpeningIndicatorRegex: RegExp, mathEndingIndicatorRegex: RegExp): string {
const startOfLine = text.substring(getStartOfLineIndex(text, mathBlockStartIndex), mathBlockStartIndex) ?? '';
const [lineStart] = getStartOfLineWhitespaceOrBlockquoteLevel(startOfLine, startOfLine.length);
const startOfEndingLine = text.substring(getStartOfLineIndex(text, mathBlockEndIndex), mathBlockEndIndex) ?? '';
const emptyLineBlockquoteRegex = /^(>( |\t)*)+\$+$/m;
let mathBlock = text.substring(mathBlockStartIndex, mathBlockEndIndex);
const isBlockquote = startsWithBlockquote.test(startOfLine.trim());
let startingNewLineAdded = false;

mathBlock = mathBlock.replace(mathOpeningIndicatorRegex, (_: string, $1: string, $2: string = '') => {
let newOpening = '';
if (!isBlockquote && startOfLine.trim() != '') {
newOpening += '\n';
startingNewLineAdded = true;
} else if (isBlockquote && !emptyLineMathBlockquoteRegex.test(startOfLine)) {
newOpening += '\n' + lineStart;
startingNewLineAdded = true;
}

newOpening += $1 + '\n';

// a new line is being added
if ($2 === '') {
return $1 + '\n' + startOfLine;
if ($2 === '' && isBlockquote) {
newOpening += lineStart;
}

return $1 + '\n';
return newOpening;
});
mathBlock= mathBlock.replace(mathEndingIndicatorRegex, (match: string, $1: string = '', $2: string, $3: string) => {
mathBlock = mathBlock.replace(mathEndingIndicatorRegex, (match: string, $1: string = '', $2: string, $3: string) => {
const groupOneIsEmpty = $1 === '';

// make sure that a blank blockquote line is checked for in order to determine if a change needs to happen just for blockquotes
if (groupOneIsEmpty && emptyLineBlockquoteRegex.test(startOfEndingLine.trim())) {
if (groupOneIsEmpty && isBlockquote && emptyLineMathBlockquoteRegex.test(startOfEndingLine.trim())) {
return match;
} else if (groupOneIsEmpty) { // a new line is being added
return '\n' + startOfLine + $2 + $3;
} else if (groupOneIsEmpty && isBlockquote) { // a new line is being added
return '\n' + lineStart + $2 + $3;
}

return '\n' + $2 + $3;
});

// try to cleanup whitespace that may get left behind by this logic when moving the opening
// math block indicators to its own line
// eslint-disable-next-line no-unmodified-loop-condition
while (startingNewLineAdded && mathBlockStartIndex > 0) {
const previousChar = text[mathBlockStartIndex-1];
if (previousChar !== ' ' && previousChar !== '\t') {
break;
}

mathBlockStartIndex--;
}

return replaceTextBetweenStartAndEndWithNewValue(text, mathBlockStartIndex, mathBlockEndIndex, mathBlock);
}

Expand Down
2 changes: 2 additions & 0 deletions src/utils/regex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export const obsidianMultilineCommentRegex = /^%%\n[^%]*\n%%/gm;
export const wordSplitterRegex = /[,\s]+/;
export const ellipsisRegex = /(\. ?){2}\./g;
export const lineStartingWithWhitespaceOrBlockquoteTemplate = `\\s*(>\\s*)*`;
export const emptyLineMathBlockquoteRegex = /^(>( |\t)*)+\$*?$/m;
export const startsWithBlockquote = /^\s*(>\s*)+/m;
export const tableSeparator = /(\|? *:?-{1,}:? *\|?)(\| *:?-{1,}:? *\|?)*( |\t)*$/gm;
export const tableStartingPipe = /^(((>[ ]?)*)|([ ]{0,3}))\|/m;
export const tableRow = /[^\n]*?\|[^\n]*?(\n|$)/m;
Expand Down

0 comments on commit 4cd434c

Please sign in to comment.