From 58cab44e1dcca6fcbdcce725439415089581feb2 Mon Sep 17 00:00:00 2001 From: JoaoEmanuell <81983803+JoaoEmanuell@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:32:48 -0300 Subject: [PATCH 1/7] feat: add support to multiples versicles --- data/books/pt-br.json | 29 +++++++++++++++++++++++++++++ src/EditorSuggester.ts | 17 ++++++----------- src/GenerateLinks.ts | 20 ++++++++++++++++---- src/Regex.ts | 2 +- src/Verse.ts | 19 +++++++++---------- tsconfig.json | 3 ++- 6 files changed, 63 insertions(+), 27 deletions(-) diff --git a/data/books/pt-br.json b/data/books/pt-br.json index 336e99a..8b70ee8 100644 --- a/data/books/pt-br.json +++ b/data/books/pt-br.json @@ -1,30 +1,37 @@ { "GEN": [ "gênesis", + "genesis", "gn" ], "EXO": [ "êxodo", + "exodo", "ex" ], "LEV": [ "levítico", + "levitico", "lv" ], "NUM": [ "números", + "numeros", "nm" ], "DEU": [ "deuteronômio", + "deuteronomio", "dt" ], "JOS": [ "josué", + "josue", "js" ], "JDG": [ "juízes", + "juizes", "jz" ], "RUT": [ @@ -49,10 +56,12 @@ ], "1CH": [ "1crônicas", + "1cronicas", "1cr" ], "2CH": [ "2crônicas", + "2cronicas", "2cr" ], "EZR": [ @@ -76,6 +85,7 @@ ], "PRO": [ "provérbios", + "proverbios", "pv" ], "ECC": [ @@ -84,10 +94,14 @@ ], "SNG": [ "cantaresdesalomão", + "cantares", + "cânticodoscânticos", + "canticodoscanticos", "ct" ], "ISA": [ "isaías", + "isaias", "is" ], "JER": [ @@ -96,6 +110,8 @@ ], "LAM": [ "lamentações", + "lamentaçoes", + "lamentacoes", "lm" ], "EZK": [ @@ -108,6 +124,7 @@ ], "HOS": [ "oséias", + "oseias", "os" ], "JOL": [ @@ -116,6 +133,7 @@ ], "AMO": [ "amós", + "amos", "am" ], "OBA": [ @@ -128,6 +146,7 @@ ], "MIC": [ "miquéias", + "miqueias", "mq" ], "NAM": [ @@ -168,6 +187,7 @@ ], "JHN": [ "joão", + "joao", "jo" ], "ACT": [ @@ -180,18 +200,22 @@ ], "1CO": [ "1coríntios", + "1corintios", "1co" ], "2CO": [ "2coríntios", + "2corintios", "2co" ], "GAL": [ "gálatas", + "galatas", "gl" ], "EPH": [ "efésios", + "efesios", "ef" ], "PHP": [ @@ -212,10 +236,12 @@ ], "1TI": [ "1timóteo", + "1timoteo", "1tm" ], "2TI": [ "2timóteo", + "2timoteo", "2tm" ], "TIT": [ @@ -244,14 +270,17 @@ ], "1JN": [ "1joão", + "1joao", "1jo" ], "2JN": [ "2joão", + "2joao", "2jo" ], "3JN": [ "3joão", + "3joao", "3jo" ], "JUD": [ diff --git a/src/EditorSuggester.ts b/src/EditorSuggester.ts index 2cecc22..958cd29 100644 --- a/src/EditorSuggester.ts +++ b/src/EditorSuggester.ts @@ -26,9 +26,8 @@ export class EditorSuggester extends EditorSuggest { cursor: EditorPosition, editor: Editor, file: TFile | null - ): EditorSuggestTriggerInfo | null { + ): EditorSuggestTriggerInfo | null { const currentLine = editor.getLine(cursor.line); - const link_pos = currentLine.search( new RegExp(this.settings.linkTrigger, "u") ); @@ -116,14 +115,12 @@ export function getSuggestionsFromQuery( return []; } - const numbersPartsOfQueryString = query.substring(bookName.length); + const numbersPartsOfQueryString = query.substring(bookName.length); const numbers = numbersPartsOfQueryString.split(separatorRegex); - + const verses = numbersPartsOfQueryString.split(':')[1].replaceAll(' ', '').trim() // get verses provide by user const chapterNumber = parseInt(numbers[0]); const verseNumber = numbers.length > 1 ? parseInt(numbers[1]) : undefined; - const verseEndNumber = - numbers.length === 3 ? parseInt(numbers[2]) : undefined; - + return booksUrl.flatMap( (bookUrl) => settings.bibleVersions @@ -134,8 +131,7 @@ export function getSuggestionsFromQuery( bookUrl, bookName, chapterNumber, - verseNumber, - verseEndNumber + verses ); } else if (verseNumber !== undefined) { return new VerseEmbed( @@ -143,8 +139,7 @@ export function getSuggestionsFromQuery( bookUrl, bookName, chapterNumber, - verseNumber, - verseEndNumber + verses ); } }) diff --git a/src/GenerateLinks.ts b/src/GenerateLinks.ts index 5495d52..8b2bda1 100644 --- a/src/GenerateLinks.ts +++ b/src/GenerateLinks.ts @@ -2,25 +2,37 @@ import { Editor, MarkdownView } from "obsidian"; import { linkRegex } from "./Regex"; import { getSuggestionsFromQuery } from "./EditorSuggester"; import { ObsidianYouversionLinkerSettings } from "./SettingsData"; +import Verse from "./Verse"; export default function GenerateLinks( editor: Editor, view: MarkdownView, settings: ObsidianYouversionLinkerSettings ) { + const removeDuplicatedSuggestionsHandler = (suggestions: Verse[]) => { + // remove duplicated suggestions + suggestions.map((suggestion) => { + const index = suggestions.indexOf(suggestion); + if (index >= 0) { + suggestions = suggestions.slice(index, 1) + } + }) + return suggestions + } + const lines = editor.lineCount(); for (let i = 0; i < lines; i++) { const line = editor.getLine(i); - const match = [...line.matchAll(linkRegex)]; + const match = [...line.matchAll(linkRegex)]; match.forEach((match) => { - const suggestions = getSuggestionsFromQuery( + const suggestions = removeDuplicatedSuggestionsHandler(getSuggestionsFromQuery( match[0], true, settings - ); + )); suggestions.forEach(async (s) => { - if (match.index === undefined) return; + if (match.index === undefined) return; editor.replaceRange( await s.toReplace(), { diff --git a/src/Regex.ts b/src/Regex.ts index 7c88729..4b09568 100644 --- a/src/Regex.ts +++ b/src/Regex.ts @@ -1,5 +1,5 @@ export const linkRegex = - /([12345]\s?)?\p{L}+\s?\d{1,3}([:,.]\s?\d{1,3}([-–]\d{1,3})?)?/gu; + /([12345]\s?)?\p{L}+\s?\d{1,3}[:,.]\s?\d{1,3}([-–]\d{1,3})?(,\s?\d{1,3}([-–]\d{1,3})?)*/gu; export const bookRegex = /([12345]\s?)?\p{L}+/u; diff --git a/src/Verse.ts b/src/Verse.ts index 9b3094e..fb89bce 100644 --- a/src/Verse.ts +++ b/src/Verse.ts @@ -7,8 +7,7 @@ export default abstract class Verse { private bookUrl: string, private book: string, private chapter: number, - private verse: number | undefined, - private verseEnd: number | undefined + private verses: string ) {} public render(el: HTMLElement) { @@ -24,11 +23,12 @@ export default abstract class Verse { } toSimpleText() { - return this.verse - ? this.verseEnd - ? `${this.book} ${this.chapter}:${this.verse}-${this.verseEnd}` - : `${this.book} ${this.chapter}:${this.verse}` - : `${this.book} ${this.chapter}`; + const formatBookNameHandler = (book: string) => { + return book.charAt(0).toUpperCase() + book.toLowerCase().slice(1); + } + return this.verses + ? `${formatBookNameHandler(this.book)} ${this.chapter}:${this.verses.replaceAll(',', ', ')}` + : `${formatBookNameHandler(this.book)} ${this.chapter}`; } abstract toReplace(): Promise; @@ -36,9 +36,8 @@ export default abstract class Verse { getUrl(): string { const base = "https://www.bible.com/bible"; let url = `${base}/${this.version.id}/${this.bookUrl}.${this.chapter}`; - if (this.verse) { - url += `.${this.verse}`; - if (this.verseEnd) url += `-${this.verseEnd}`; + if (this.verses) { + url += `.${this.verses}`; } return url; } diff --git a/tsconfig.json b/tsconfig.json index 3bb0220..c7e1c52 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,8 @@ "DOM", "ES5", "ES6", - "ES7" + "ES7", + "ES2021.String" ] }, "include": [ From 87878eed6f5a5d47f18074d009b45bb95cce4292 Mon Sep 17 00:00:00 2001 From: JoaoEmanuell <81983803+JoaoEmanuell@users.noreply.github.com> Date: Tue, 17 Sep 2024 18:00:06 -0300 Subject: [PATCH 2/7] refactor: regex added support to texts like 5mos 12, ps78 --- src/Regex.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Regex.ts b/src/Regex.ts index 4b09568..c2e6288 100644 --- a/src/Regex.ts +++ b/src/Regex.ts @@ -1,5 +1,4 @@ -export const linkRegex = - /([12345]\s?)?\p{L}+\s?\d{1,3}[:,.]\s?\d{1,3}([-–]\d{1,3})?(,\s?\d{1,3}([-–]\d{1,3})?)*/gu; +export const linkRegex = /([12345]?\p{L}{2,}\d?\s?\d{1,3}([:,.]\s?\d{1,3}([-–]\d{1,3})?)?(,\s?\d{1,3}([-–]\d{1,3})?)*)/gu; export const bookRegex = /([12345]\s?)?\p{L}+/u; From caf75cd0bf305a124dfb0a4a1d36d8fb991e63a7 Mon Sep 17 00:00:00 2001 From: JoaoEmanuell <81983803+JoaoEmanuell@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:15:10 -0300 Subject: [PATCH 3/7] =?UTF-8?q?refactor:=20added=20support=20for=20',',=20?= =?UTF-8?q?'.',=20'=E2=80=94'=20in=20verses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/EditorSuggester.ts | 8 ++++++-- src/Regex.ts | 5 +++-- src/Verse.ts | 10 ++++------ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/EditorSuggester.ts b/src/EditorSuggester.ts index 958cd29..00d7190 100644 --- a/src/EditorSuggester.ts +++ b/src/EditorSuggester.ts @@ -26,7 +26,7 @@ export class EditorSuggester extends EditorSuggest { cursor: EditorPosition, editor: Editor, file: TFile | null - ): EditorSuggestTriggerInfo | null { + ): EditorSuggestTriggerInfo | null { const currentLine = editor.getLine(cursor.line); const link_pos = currentLine.search( new RegExp(this.settings.linkTrigger, "u") @@ -117,7 +117,11 @@ export function getSuggestionsFromQuery( const numbersPartsOfQueryString = query.substring(bookName.length); const numbers = numbersPartsOfQueryString.split(separatorRegex); - const verses = numbersPartsOfQueryString.split(':')[1].replaceAll(' ', '').trim() // get verses provide by user + let verses: string; + if (numbers.length !== 1) { + verses = numbersPartsOfQueryString.split(/[:,.]/).slice(1).join(',') // split the verses of the chapter, join the verses using a ',' for separate verses. + } + const chapterNumber = parseInt(numbers[0]); const verseNumber = numbers.length > 1 ? parseInt(numbers[1]) : undefined; diff --git a/src/Regex.ts b/src/Regex.ts index c2e6288..e3e2d5f 100644 --- a/src/Regex.ts +++ b/src/Regex.ts @@ -1,8 +1,9 @@ -export const linkRegex = /([12345]?\p{L}{2,}\d?\s?\d{1,3}([:,.]\s?\d{1,3}([-–]\d{1,3})?)?(,\s?\d{1,3}([-–]\d{1,3})?)*)/gu; +export const linkRegex = + /([12345]?\p{L}{2,}\d?\s?\d{1,3}([:,.]\s?\d{1,3}([-–—]\d{1,3})?)?(,\s?\d{1,3}([-–—]\d{1,3})?)*)/gu; export const bookRegex = /([12345]\s?)?\p{L}+/u; -export const separatorRegex = /[-:,.–]+/; +export const separatorRegex = /[-:,.–—]+/; export const htmlDataRegex = /.+?(?=<\/script>\s*<\/body>\s*<\/html>)/; diff --git a/src/Verse.ts b/src/Verse.ts index fb89bce..fffc56c 100644 --- a/src/Verse.ts +++ b/src/Verse.ts @@ -23,12 +23,9 @@ export default abstract class Verse { } toSimpleText() { - const formatBookNameHandler = (book: string) => { - return book.charAt(0).toUpperCase() + book.toLowerCase().slice(1); - } return this.verses - ? `${formatBookNameHandler(this.book)} ${this.chapter}:${this.verses.replaceAll(',', ', ')}` - : `${formatBookNameHandler(this.book)} ${this.chapter}`; + ? `${this.book} ${this.chapter}:${this.verses}` + : `${this.book} ${this.chapter}`; } abstract toReplace(): Promise; @@ -37,7 +34,8 @@ export default abstract class Verse { const base = "https://www.bible.com/bible"; let url = `${base}/${this.version.id}/${this.bookUrl}.${this.chapter}`; if (this.verses) { - url += `.${this.verses}`; + url += `.${this.verses.replaceAll(' ', '').replaceAll(/[–—]/g, '-').trim()}`; + // remove the empty spaces and replace the en-dash to normal dash to insert the verses in URL } return url; } From b10c8956833be3d856eed54a9d66cbb63853c5cb Mon Sep 17 00:00:00 2001 From: JoaoEmanuell <81983803+JoaoEmanuell@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:24:33 -0300 Subject: [PATCH 4/7] refactor: removed spaces on right of the code --- src/EditorSuggester.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EditorSuggester.ts b/src/EditorSuggester.ts index 00d7190..7a283c5 100644 --- a/src/EditorSuggester.ts +++ b/src/EditorSuggester.ts @@ -115,7 +115,7 @@ export function getSuggestionsFromQuery( return []; } - const numbersPartsOfQueryString = query.substring(bookName.length); + const numbersPartsOfQueryString = query.substring(bookName.length); const numbers = numbersPartsOfQueryString.split(separatorRegex); let verses: string; if (numbers.length !== 1) { From 0e1f43237700ba11daa83ab1f8d5b85a1a96007c Mon Sep 17 00:00:00 2001 From: jaanonim Date: Wed, 18 Sep 2024 18:40:14 +0200 Subject: [PATCH 5/7] change verses to list of VerseElements --- src/EditorSuggester.ts | 39 ++++++++++++++++++++++++----------- src/Regex.ts | 5 +++-- src/Verse.ts | 27 ++++++++++++++++++------ test/regex.test.ts | 47 +++++++++--------------------------------- tsconfig.json | 3 +-- 5 files changed, 62 insertions(+), 59 deletions(-) diff --git a/src/EditorSuggester.ts b/src/EditorSuggester.ts index 7a283c5..cc13355 100644 --- a/src/EditorSuggester.ts +++ b/src/EditorSuggester.ts @@ -1,7 +1,12 @@ import getBooks from "./Books"; -import { bookRegex, linkRegex, separatorRegex } from "./Regex"; +import { + bookRegex, + linkRegex, + chapterSeparatorRegex, + rangeSeparatorRegex, +} from "./Regex"; import { ObsidianYouversionLinkerSettings } from "./SettingsData"; -import Verse from "./Verse"; +import Verse, { VerseElement } from "./Verse"; import VerseEmbed from "./VerseEmbed"; import VerseLink from "./VerseLink"; import ObsidianYouversionLinker from "./main"; @@ -96,6 +101,19 @@ export class EditorSuggester extends EditorSuggest { } } +export function processVerses(verses_str: Array): Array { + return verses_str + .map((verse) => { + const [start, end] = verse + .split(rangeSeparatorRegex) + .map((v) => (v === undefined ? undefined : parseInt(v))); + return start === undefined + ? undefined + : new VerseElement(start, end); + }) + .filter((v) => v !== undefined) as Array; +} + export function getSuggestionsFromQuery( query: string, isLink: boolean, @@ -116,15 +134,12 @@ export function getSuggestionsFromQuery( } const numbersPartsOfQueryString = query.substring(bookName.length); - const numbers = numbersPartsOfQueryString.split(separatorRegex); - let verses: string; - if (numbers.length !== 1) { - verses = numbersPartsOfQueryString.split(/[:,.]/).slice(1).join(',') // split the verses of the chapter, join the verses using a ',' for separate verses. - } - - const chapterNumber = parseInt(numbers[0]); - const verseNumber = numbers.length > 1 ? parseInt(numbers[1]) : undefined; - + const [chapter_str, ...verses_str] = numbersPartsOfQueryString.split( + chapterSeparatorRegex + ); + const verses = processVerses(verses_str); + const chapterNumber = parseInt(chapter_str); + return booksUrl.flatMap( (bookUrl) => settings.bibleVersions @@ -137,7 +152,7 @@ export function getSuggestionsFromQuery( chapterNumber, verses ); - } else if (verseNumber !== undefined) { + } else if (verses.length !== 0) { return new VerseEmbed( version, bookUrl, diff --git a/src/Regex.ts b/src/Regex.ts index e3e2d5f..628ccb1 100644 --- a/src/Regex.ts +++ b/src/Regex.ts @@ -1,9 +1,10 @@ export const linkRegex = - /([12345]?\p{L}{2,}\d?\s?\d{1,3}([:,.]\s?\d{1,3}([-–—]\d{1,3})?)?(,\s?\d{1,3}([-–—]\d{1,3})?)*)/gu; + /([12345]\s?)?\p{L}+\s?\d{1,3}([:,.]\s?\d{1,3}([-–—]\d{1,3})?)?([,.]\s?\d{1,3}([-–—]\d{1,3})?)*/gu; export const bookRegex = /([12345]\s?)?\p{L}+/u; -export const separatorRegex = /[-:,.–—]+/; +export const chapterSeparatorRegex = /[:,.]+/; +export const rangeSeparatorRegex = /[-–—]+/; export const htmlDataRegex = /.+?(?=<\/script>\s*<\/body>\s*<\/html>)/; diff --git a/src/Verse.ts b/src/Verse.ts index fffc56c..784a8b6 100644 --- a/src/Verse.ts +++ b/src/Verse.ts @@ -1,13 +1,27 @@ import { BibleVersion } from "./SettingsData"; import VERSIONS from "../data/versions.json"; +export class VerseElement { + public start: number; + public end: number | undefined; + + public constructor(start: number, end: number | undefined) { + this.start = start; + this.end = end; + } + + public toString() { + return `${this.start}${this.end ? `-${this.end}` : ""}`; + } +} + export default abstract class Verse { constructor( private version: BibleVersion, private bookUrl: string, private book: string, private chapter: number, - private verses: string + private verses: Array ) {} public render(el: HTMLElement) { @@ -23,8 +37,10 @@ export default abstract class Verse { } toSimpleText() { - return this.verses - ? `${this.book} ${this.chapter}:${this.verses}` + return this.verses.length > 0 + ? `${this.book} ${this.chapter}:${this.verses + .map((verse) => verse.toString()) + .join(", ")}` : `${this.book} ${this.chapter}`; } @@ -33,9 +49,8 @@ export default abstract class Verse { getUrl(): string { const base = "https://www.bible.com/bible"; let url = `${base}/${this.version.id}/${this.bookUrl}.${this.chapter}`; - if (this.verses) { - url += `.${this.verses.replaceAll(' ', '').replaceAll(/[–—]/g, '-').trim()}`; - // remove the empty spaces and replace the en-dash to normal dash to insert the verses in URL + if (this.verses.length > 0) { + url += `.${this.verses.map((verse) => verse.toString()).join(",")}`; } return url; } diff --git a/test/regex.test.ts b/test/regex.test.ts index 4bafdd1..c0a3aff 100644 --- a/test/regex.test.ts +++ b/test/regex.test.ts @@ -1,4 +1,4 @@ -import { bookRegex, linkRegex, separatorRegex } from "../src/Regex"; +import { bookRegex, linkRegex } from "../src/Regex"; describe("Regex Tests", () => { // Tests for linkRegex @@ -23,7 +23,7 @@ describe("Regex Tests", () => { expect("matt 9").toMatch(linkRegex); }); - test('matches "jes 9, 10"', () => { + test('matches "jes 9, 10.1"', () => { expect("jes 9,10").toMatch(linkRegex); }); @@ -34,6 +34,14 @@ describe("Regex Tests", () => { test('matches "3 こんにちは 123"', () => { expect("3 こんにちは 123").toMatch(linkRegex); }); + + test('matches "3 こんにちは 123.5"', () => { + expect("3 こんにちは 123").toMatch(linkRegex); + }); + + test('matches "jes 9:10-11.1-3,45"', () => { + expect("jes 9:10-11").toMatch(linkRegex); + }); }); // Tests for bookRegex @@ -70,39 +78,4 @@ describe("Regex Tests", () => { expect("123").not.toMatch(bookRegex); }); }); - - // Tests for separatorRegex - describe("separatorRegex", () => { - test('matches "-"', () => { - expect("-").toMatch(separatorRegex); - }); - - test('matches ":"', () => { - expect(":").toMatch(separatorRegex); - }); - - test('matches ","', () => { - expect(",").toMatch(separatorRegex); - }); - - test('matches "."', () => { - expect(".").toMatch(separatorRegex); - }); - - test('matches "---"', () => { - expect("---").toMatch(separatorRegex); - }); - - test('matches "..."', () => { - expect("...").toMatch(separatorRegex); - }); - - test('does not match "abc"', () => { - expect("abc").not.toMatch(separatorRegex); - }); - - test('does not match "1"', () => { - expect("1").not.toMatch(separatorRegex); - }); - }); }); diff --git a/tsconfig.json b/tsconfig.json index c7e1c52..3bb0220 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,8 +17,7 @@ "DOM", "ES5", "ES6", - "ES7", - "ES2021.String" + "ES7" ] }, "include": [ From ab9ea6f1f12c0e88123e33804d901793bbf345dd Mon Sep 17 00:00:00 2001 From: jaanonim Date: Wed, 18 Sep 2024 18:43:29 +0200 Subject: [PATCH 6/7] formatting --- src/GenerateLinks.ts | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/GenerateLinks.ts b/src/GenerateLinks.ts index 8b2bda1..530c56a 100644 --- a/src/GenerateLinks.ts +++ b/src/GenerateLinks.ts @@ -14,25 +14,23 @@ export default function GenerateLinks( suggestions.map((suggestion) => { const index = suggestions.indexOf(suggestion); if (index >= 0) { - suggestions = suggestions.slice(index, 1) + suggestions = suggestions.slice(index, 1); } - }) - return suggestions - } - + }); + return suggestions; + }; + const lines = editor.lineCount(); for (let i = 0; i < lines; i++) { const line = editor.getLine(i); - const match = [...line.matchAll(linkRegex)]; + const match = [...line.matchAll(linkRegex)]; match.forEach((match) => { - const suggestions = removeDuplicatedSuggestionsHandler(getSuggestionsFromQuery( - match[0], - true, - settings - )); + const suggestions = removeDuplicatedSuggestionsHandler( + getSuggestionsFromQuery(match[0], true, settings) + ); suggestions.forEach(async (s) => { - if (match.index === undefined) return; + if (match.index === undefined) return; editor.replaceRange( await s.toReplace(), { From 5f36f1b318ea28c310fdb7bca01732465494be38 Mon Sep 17 00:00:00 2001 From: jaanonim Date: Thu, 19 Sep 2024 14:30:32 +0200 Subject: [PATCH 7/7] add note in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index abff26a..ddb36b2 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ **List of supported languages can be found [here](./Languages.md).** -You need to just type for example: `@ John 1:1-6` to link verse to quote verse use for example: `> John 1:1-6`. +You need to just type for example: `@ John 1:1-6` to link verse to quote verse use for example: `> John 1:1-6`. Now it also supports multiple verses like: `John 3:16,18-20`. `@` and `>` char is a trigger for suggestion and it can be changed in settings. In settings you can select witch version of bible you want to use and books names in witch language will be detected.