Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions __tests__/move-footnotes-to-the-bottom.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,5 +305,25 @@ ruleTest({
[^3]: [3333](333)
`,
},
{ // accounts for https://github.com/platers/obsidian-linter/issues/1392
testName: 'Moving footnotes to the bottom of the file when including blank lines between footnotes should not change a file with footnotes at the end with blank lines between them already',
before: dedent`
This is the first footnote.[^1] This is the second.[^2]
${''}
[^1]: Hey, I am a footnote!
${''}
[^2]: Me too!
`,
after: dedent`
This is the first footnote.[^1] This is the second.[^2]
${''}
[^1]: Hey, I am a footnote!
${''}
[^2]: Me too!
`,
options: {
includeBlankLineBetweenFootnotes: true,
},
},
],
});
4 changes: 4 additions & 0 deletions src/lang/locale/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,10 @@ export default {
'move-footnotes-to-the-bottom': {
'name': 'Move Footnotes to the bottom',
'description': 'Move all footnotes to the bottom of the document and makes sure they are sorted based on the order they are referenced in the file\'s body.',
'include-blank-line-between-footnotes': {
'name': 'Include Blank Line Between Footnotes',
'description': 'Includes a blank line between footnotes when enabled.',
},
},
// move-math-block-indicators-to-their-own-line.ts
'move-math-block-indicators-to-their-own-line': {
Expand Down
43 changes: 39 additions & 4 deletions src/rules/move-footnotes-to-the-bottom.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {Options, RuleType} from '../rules';
import RuleBuilder, {ExampleBuilder, OptionBuilderBase} from './rule-builder';
import RuleBuilder, {BooleanOptionBuilder, ExampleBuilder, OptionBuilderBase} from './rule-builder';
import dedent from 'ts-dedent';
import {IgnoreTypes} from '../utils/ignore-types';
import {moveFootnotesToEnd} from '../utils/mdast';

class MoveFootnotesToTheBottomOptions implements Options {}
class MoveFootnotesToTheBottomOptions implements Options {
includeBlankLineBetweenFootnotes?: boolean = false;
}

@RuleBuilder.register
export default class MoveFootnotesToTheBottom extends RuleBuilder<MoveFootnotesToTheBottomOptions> {
Expand All @@ -20,7 +22,7 @@ export default class MoveFootnotesToTheBottom extends RuleBuilder<MoveFootnotesT
return MoveFootnotesToTheBottomOptions;
}
apply(text: string, options: MoveFootnotesToTheBottomOptions): string {
return moveFootnotesToEnd(text);
return moveFootnotesToEnd(text, options.includeBlankLineBetweenFootnotes);
}
get exampleBuilders(): ExampleBuilder<MoveFootnotesToTheBottomOptions>[] {
return [
Expand All @@ -46,9 +48,42 @@ export default class MoveFootnotesToTheBottom extends RuleBuilder<MoveFootnotesT
[^2]: second footnote
`,
}),
new ExampleBuilder({
description: 'Moving footnotes to the bottom with including a blank line between footnotes',
before: dedent`
Lorem ipsum, consectetur adipiscing elit. [^1] Donec dictum turpis quis ipsum pellentesque.
${''}
[^1]: first footnote
${''}
Quisque lorem est, fringilla sed enim at, sollicitudin lacinia nisi.[^2]
[^2]: second footnote
${''}
Maecenas malesuada dignissim purus ac volutpat.
`,
after: dedent`
Lorem ipsum, consectetur adipiscing elit. [^1] Donec dictum turpis quis ipsum pellentesque.
${''}
Quisque lorem est, fringilla sed enim at, sollicitudin lacinia nisi.[^2]
Maecenas malesuada dignissim purus ac volutpat.
${''}
[^1]: first footnote
${''}
[^2]: second footnote
`,
options: {
includeBlankLineBetweenFootnotes: true,
},
}),
];
}
get optionBuilders(): OptionBuilderBase<MoveFootnotesToTheBottomOptions>[] {
return [];
return [
new BooleanOptionBuilder({
OptionsClass: MoveFootnotesToTheBottomOptions,
nameKey: 'rules.move-footnotes-to-the-bottom.include-blank-line-between-footnotes.name',
descriptionKey: 'rules.move-footnotes-to-the-bottom.include-blank-line-between-footnotes.description',
optionsKey: 'includeBlankLineBetweenFootnotes',
}),
];
}
}
14 changes: 11 additions & 3 deletions src/utils/mdast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,10 @@ function getHeaderTextPositions(text: string): PositionPlusText[] {
/**
* Moves footnote declarations to the end of the document.
* @param {string} text The text to move footnotes in
* @param {boolean} includeBlankLinesBetweenFootnotes Whether to have a blank line between footnotes
* @return {string} The text with footnote declarations moved to the end
*/
export function moveFootnotesToEnd(text: string): string {
export function moveFootnotesToEnd(text: string, includeBlankLinesBetweenFootnotes: boolean): string {
const positions: Position[] = getPositions(MDAstTypes.Footnote, text);
let footnotes: string[] = [];

Expand Down Expand Up @@ -273,10 +274,17 @@ export function moveFootnotesToEnd(text: string): string {

// Add the footnotes to the end of the document
if (footnotes.length > 0) {
text = text.trimEnd() + '\n';
text = text.trimEnd();
}
let whitespaceBetweenFootnotes = '\n';
if (includeBlankLinesBetweenFootnotes) {
whitespaceBetweenFootnotes = '\n\n';
} else {
text += '\n';
}

for (const footnote of footnotes) {
text += '\n' + footnote;
text += whitespaceBetweenFootnotes + footnote;
}

return text;
Expand Down