2 - Added support for Bible Linker style Bible formatting.

This commit is contained in:
Caleb Campbell
2025-12-20 09:25:59 +11:00
parent ae93bb1ccb
commit 6973fdcbdc
4 changed files with 83 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
import { Plugin } from 'obsidian'; import { Plugin } from 'obsidian';
import LocalBibleRefSettingTab from 'src/local-bible-ref-setting-tab'; import LocalBibleRefSettingTab, { BibleFormat } from 'src/local-bible-ref-setting-tab';
import { PassageFormat } from 'src/passage-reference'; import { PassageFormat } from 'src/passage-reference';
import { PassageSuggest } from 'src/passage-suggest'; import { PassageSuggest } from 'src/passage-suggest';
import { LocalBibleRefSettings } from 'src/settings'; import { LocalBibleRefSettings } from 'src/settings';
@@ -20,7 +20,8 @@ export default class LocalBibleRefPlugin extends Plugin {
this.settings ??= { this.settings ??= {
biblesPath: '', biblesPath: '',
defaultVersionShorthand: '', defaultVersionShorthand: '',
defaultPassageFormat: PassageFormat.Callout defaultPassageFormat: PassageFormat.Callout,
bibleFormat: BibleFormat.LocalBibleRef,
}; };
} }

View File

@@ -16,6 +16,10 @@ export default class LocalBibleRefSettingTab extends PluginSettingTab {
const { containerEl } = this; const { containerEl } = this;
containerEl.empty(); containerEl.empty();
new Setting(containerEl)
.setName('Configurations')
.setHeading();
let biblesPathTimeout: number; let biblesPathTimeout: number;
new Setting(containerEl) new Setting(containerEl)
.setName('Bibles path') .setName('Bibles path')
@@ -48,6 +52,10 @@ export default class LocalBibleRefSettingTab extends PluginSettingTab {
new PathSuggest(this.app, text.inputEl); new PathSuggest(this.app, text.inputEl);
}); });
new Setting(containerEl)
.setName('Defaults')
.setHeading();
let defaultVersionTimeout: number; let defaultVersionTimeout: number;
const defaultVersionSetting = new Setting(containerEl) const defaultVersionSetting = new Setting(containerEl)
.setName('Default version shorthand') .setName('Default version shorthand')
@@ -90,5 +98,24 @@ export default class LocalBibleRefSettingTab extends PluginSettingTab {
this.plugin.settings.defaultPassageFormat = value as PassageFormat; this.plugin.settings.defaultPassageFormat = value as PassageFormat;
await this.plugin.saveSettings(); await this.plugin.saveSettings();
})); }));
new Setting(containerEl)
.setName('Bible Format')
.setDesc('The formatting style you use for your vault bibles. Local Bible Ref relies on this to parse passages correctly.')
.addDropdown(dropdown => dropdown
.addOptions({
localBibleRef: 'Local Bible Ref',
bibleLinker: 'Bible Linker',
})
.setValue(this.plugin.settings.bibleFormat)
.onChange(async (value) => {
this.plugin.settings.bibleFormat = value as BibleFormat;
await this.plugin.saveSettings();
}));
} }
}
export enum BibleFormat {
LocalBibleRef = 'localBibleRef',
BibleLinker = 'bibleLinker',
} }

View File

@@ -12,6 +12,7 @@ import {
} from "obsidian"; } from "obsidian";
import { PassageFormat, PassageReference } from "./passage-reference"; import { PassageFormat, PassageReference } from "./passage-reference";
import { LocalBibleRefSettings } from "./settings"; import { LocalBibleRefSettings } from "./settings";
import { BibleFormat } from "./local-bible-ref-setting-tab";
export class PassageSuggest extends EditorSuggest<PassageSuggestion> { export class PassageSuggest extends EditorSuggest<PassageSuggestion> {
private settings: LocalBibleRefSettings; private settings: LocalBibleRefSettings;
@@ -105,7 +106,7 @@ export class PassageSuggest extends EditorSuggest<PassageSuggestion> {
}); });
// suggest // suggest
const excerpt = this.generateExcerpt(texts[0]); const excerpt = this.generateExcerpt(texts[0]);
const text = this.formatTexts(texts, passageRef, context); const text = this.formatTexts(texts, passageRef, context);
return [{ excerpt, text }]; return [{ excerpt, text }];
} }
@@ -164,9 +165,17 @@ export class PassageSuggest extends EditorSuggest<PassageSuggestion> {
text: string, text: string,
ref: PassageReference ref: PassageReference
): string | null { ): string | null {
const regExp = new RegExp( let pattern = '';
`(?:[>-] )*(?:\\*\\*\\d{1,3}\\*\\* )?<sup>${ref.startVerse}</sup>` if (this.settings.bibleFormat === BibleFormat.BibleLinker) {
); pattern = `#{1,6} [a-zA-Z]*${ref.startVerse}[a-zA-Z]*\\n\\w+`;
} else {
const quoteOrList = '(?:[>-] )*';
const chapterNum = '(?:\\*\\*\\d{1,3}\\*\\* )?';
const verseNum = `<sup>${ref.startVerse}</sup>`;
pattern = quoteOrList + chapterNum + verseNum;
}
const regExp = new RegExp(pattern);
const match = text.match(regExp); const match = text.match(regExp);
if (!match) return null; if (!match) return null;
@@ -181,10 +190,17 @@ export class PassageSuggest extends EditorSuggest<PassageSuggestion> {
ref: PassageReference ref: PassageReference
): string | null { ): string | null {
if (ref.endVerse === -1) return text; if (ref.endVerse === -1) return text;
const regex = new RegExp(
`(?:^(?:> |- )*)?<sup>${ref.endVerse + 1}</sup>`, let pattern = '';
"m" if (this.settings.bibleFormat === BibleFormat.BibleLinker) {
); pattern = `#{1,6} [a-zA-Z]*${ref.endVerse + 1}[a-zA-Z]*\\n\\w+`;
} else {
const quoteOrList = '(?:[>-] )*';
const verseNum = `<sup>${ref.endVerse + 1}</sup>`;
pattern = quoteOrList + verseNum;
}
const regex = new RegExp(pattern);
return text.split(regex, 1)[0].trim(); return text.split(regex, 1)[0].trim();
} }
@@ -193,12 +209,20 @@ export class PassageSuggest extends EditorSuggest<PassageSuggestion> {
chapterNumber: number, chapterNumber: number,
multipleChapters: boolean multipleChapters: boolean
): string { ): string {
if (this.settings.bibleFormat === BibleFormat.BibleLinker) {
text = this.formatBibleLinkerVerses(text);
}
text = this.removeChapterNumbers(text); text = this.removeChapterNumbers(text);
text = this.removeHeadings(text); text = this.removeHeadings(text);
text = this.removeFootnoteRefs(text); text = this.removeFootnoteRefs(text);
text = this.removeBOF(text); text = this.removeBOF(text);
text = this.removeEOF(text); text = this.removeEOF(text);
if (this.settings.bibleFormat === BibleFormat.BibleLinker) {
text = this.removeVerseSpacing(text);
}
const chapterMd = multipleChapters ? `**${chapterNumber}**` : ""; const chapterMd = multipleChapters ? `**${chapterNumber}**` : "";
if (text.startsWith("> ")) { if (text.startsWith("> ")) {
const quoteMd = text.match(/^(?:> )+/)![0]; const quoteMd = text.match(/^(?:> )+/)![0];
@@ -213,6 +237,14 @@ export class PassageSuggest extends EditorSuggest<PassageSuggestion> {
return (text = `${chapterMd} ${text}`); return (text = `${chapterMd} ${text}`);
} }
/** Formats verses that use Bible Linker formatting. */
private formatBibleLinkerVerses(text: string): string {
return text.replace(
/#{1,6} [a-zA-Z]*(\d{1,3})[a-zA-Z]*\n(\w+)/g,
"<sup>$1</sup> $2",
);
}
/** Removes chapter numbers from the given text. */ /** Removes chapter numbers from the given text. */
private removeChapterNumbers(text: string): string { private removeChapterNumbers(text: string): string {
return text.replace(/\*\*\d{1,3}\*\* /g, ""); return text.replace(/\*\*\d{1,3}\*\* /g, "");
@@ -245,6 +277,11 @@ export class PassageSuggest extends EditorSuggest<PassageSuggestion> {
return split[0].trim(); return split[0].trim();
} }
/** Removes extra spacing between verses in Bible Linker formatting. */
private removeVerseSpacing(text: string): string {
return text.replace(/\n{2,}/g, " ");
}
/** Generates an excerpt for the suggestion. */ /** Generates an excerpt for the suggestion. */
private generateExcerpt(text: string): string { private generateExcerpt(text: string): string {
text = text.split(/<\/sup>/, 2)[1]; text = text.split(/<\/sup>/, 2)[1];
@@ -302,15 +339,17 @@ export class PassageSuggest extends EditorSuggest<PassageSuggestion> {
ref: PassageReference, ref: PassageReference,
context: EditorSuggestContext context: EditorSuggestContext
): string { ): string {
const { version, book, startChapter } = ref; const { version, book, startChapter, startVerse } = ref;
const path = `${this.settings.biblesPath}/${version}/${book.name}/${book.name} ${startChapter}.md`; const path = `${this.settings.biblesPath}/${version}/${book.name}/${book.name} ${startChapter}.md`;
const file = this.app.vault.getFileByPath(normalizePath(path)); const file = this.app.vault.getFileByPath(normalizePath(path));
if (!file) return ref.stringify(); if (!file) return ref.stringify();
return this.app.fileManager.generateMarkdownLink( return this.app.fileManager.generateMarkdownLink(
file, file,
context.file.path, context.file.path,
undefined, this.settings.bibleFormat === BibleFormat.BibleLinker
? `#${startVerse}`
: undefined,
ref.stringify(), ref.stringify(),
); );
} }

View File

@@ -1,7 +1,9 @@
import { BibleFormat } from "./local-bible-ref-setting-tab";
import { PassageFormat } from "./passage-reference"; import { PassageFormat } from "./passage-reference";
export interface LocalBibleRefSettings { export interface LocalBibleRefSettings {
biblesPath: string; biblesPath: string;
defaultVersionShorthand: string; defaultVersionShorthand: string;
defaultPassageFormat: PassageFormat; defaultPassageFormat: PassageFormat;
} bibleFormat: BibleFormat;
}