diff --git a/README.md b/README.md index 6ba7cdd..0010b28 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ The original plug-in by @pacokwon required local installation of the scriptures, General Conference support essentially scrapes the given webpage for the talk title, the author information, and then the paragraph's selected. This is highly dependent on programmers keeping consistent IDs for the different HTML elements. Even between 2023 and 2023 conferences there were differences. I believe I was able to account for the differences between the different years, thanks in large part to other in the LDS GitHub community. I cannot remember whose code had solved this problem, but I'm grateful. -# NeoVim +# NeoVim Plugin If you like to use NeoVim and want similar functionality check out [LDSLibrary.nvim](https://github.com/ingiestein/LDSLibrary.nvim), and [obsidian.nvim](https://github.com/epwalsh/obsidian.nvim). diff --git a/src/env-paths.ts b/src/env-paths.ts deleted file mode 100644 index 54ee7e3..0000000 --- a/src/env-paths.ts +++ /dev/null @@ -1,79 +0,0 @@ -// NOTE: this file is from https://github.com/sindresorhus/env-paths/blob/f1729272888f45f6584e74dc4d0af3aecba9e7e8/index.js -// it is brought to this file because it originally uses "node:*" imports - -import * as path from "path"; -import * as os from "os"; -import * as process from "process"; - -const homedir = os.homedir(); -const tmpdir = os.tmpdir(); -const { env } = process; - -const macos = (name: string) => { - const library = path.join(homedir, "Library"); - - return { - data: path.join(library, "Application Support", name), - config: path.join(library, "Preferences", name), - cache: path.join(library, "Caches", name), - log: path.join(library, "Logs", name), - temp: path.join(tmpdir, name), - }; -}; - -const windows = (name: string) => { - const appData = env.APPDATA || path.join(homedir, "AppData", "Roaming"); - const localAppData = - env.LOCALAPPDATA || path.join(homedir, "AppData", "Local"); - - return { - // Data/config/cache/log are invented by me as Windows isn't opinionated about this - data: path.join(localAppData, name, "Data"), - config: path.join(appData, name, "Config"), - cache: path.join(localAppData, name, "Cache"), - log: path.join(localAppData, name, "Log"), - temp: path.join(tmpdir, name), - }; -}; - -// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html -const linux = (name: string) => { - const username = path.basename(homedir); - - return { - data: path.join( - env.XDG_DATA_HOME || path.join(homedir, ".local", "share"), - name - ), - config: path.join( - env.XDG_CONFIG_HOME || path.join(homedir, ".config"), - name - ), - cache: path.join( - env.XDG_CACHE_HOME || path.join(homedir, ".cache"), - name - ), - // https://wiki.debian.org/XDGBaseDirectorySpecification#state - log: path.join( - env.XDG_STATE_HOME || path.join(homedir, ".local", "state"), - name - ), - temp: path.join(tmpdir, username, name), - }; -}; - -export default function envPaths(name: string) { - if (typeof name !== "string") { - throw new TypeError(`Expected a string, got ${typeof name}`); - } - - if (process.platform === "darwin") { - return macos(name); - } - - if (process.platform === "win32") { - return windows(name); - } - - return linux(name); -} diff --git a/src/main.ts b/src/main.ts index 99b5261..68ec588 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,11 +1,8 @@ import { Plugin } from "obsidian"; import { BookOfMormonSettings, DEFAULT_SETTINGS } from "./settings"; import { GenConSuggester, VerseSuggester } from './suggestion/suggester'; -import { installTranslation } from "./translation"; import { BookOfMormonSettingTab } from './ui/BookOfMormonSettingTab'; -// import {fetchGenConTalk} from './utils/generalconference' - export default class BookOfMormonPlugin extends Plugin { settings: BookOfMormonSettings; @@ -14,7 +11,7 @@ export default class BookOfMormonPlugin extends Plugin { this.addSettingTab(new BookOfMormonSettingTab(this.app, this)); this.registerEditorSuggest(new VerseSuggester(this)); this.registerEditorSuggest(new GenConSuggester(this)) - // console.log("GenConSuggester Loaded"); + } onunload() {} @@ -29,7 +26,6 @@ export default class BookOfMormonPlugin extends Plugin { async saveSettings() { await this.saveData(this.settings); - await installTranslation(this.manifest.id, this.settings.language); } } diff --git a/src/metadata.ts b/src/metadata.ts deleted file mode 100644 index a134991..0000000 --- a/src/metadata.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { AvailableLanguage } from "./lang"; -import envPaths from "./env-paths"; - -export function getScripturesPath(pluginName: string, lang: AvailableLanguage): string { - const paths = envPaths(pluginName); - return `${paths.config}/translations/${lang}`; -} diff --git a/src/suggestion/VerseSuggestion.ts b/src/suggestion/VerseSuggestion.ts index f613dbf..fb3f4a5 100644 --- a/src/suggestion/VerseSuggestion.ts +++ b/src/suggestion/VerseSuggestion.ts @@ -114,7 +114,7 @@ export class VerseSuggestion { [this.book_title_short, this.volume_title_short] = this.getShortenedName(this.book); this.url = this.getUrl(); - // console.log(`Scripture URL: ${this.url}`); + let scriptdata: ScriptureData = await fetchScripture(this.url, "GET"); this.book_title_in_language = scriptdata.in_language_book this.chapter_data.push(scriptdata); diff --git a/src/suggestion/suggester.ts b/src/suggestion/suggester.ts index 8ac541b..9e40ec8 100644 --- a/src/suggestion/suggester.ts +++ b/src/suggestion/suggester.ts @@ -56,12 +56,12 @@ export class VerseSuggester extends EditorSuggest { if (fullMatch === null) return []; - // console.log("Got Match: ", fullMatch) + const book = fullMatch[1]; const chapter = Number(fullMatch[2]); const verses:number[] = this.parseVerses(fullMatch[3]); - // console.log("Book: %s\nChapter: %s\nVerses: %s",book,chapter,verses.join(',')) + const suggestion = new VerseSuggestion( this.plugin.manifest.id, @@ -95,15 +95,15 @@ export class VerseSuggester extends EditorSuggest { expandRange(range: string): number[] { const [s, e] = range.split('-'); - // console.log("Expand range strings: %s, %s",s,e); + let start = Number(s.trim()); let end = Number(e.trim()); - // console.log("Expand range ints: %s, %s",start,end); + const result = []; for (let i = start; i <= end; i++) { result.push(i); - // console.log("integer: %s", i); + } return result; } @@ -115,7 +115,7 @@ export class VerseSuggester extends EditorSuggest { for (const item of items) { if (item.includes('-')) { result = result.concat(this.expandRange(item)); - // console.log("Result from range concat: ", result) + } else { result.push(Number(item)); } @@ -145,7 +145,7 @@ export class GenConSuggester extends EditorSuggest { if (!match) { return null; } - // console.log("Found GenCon Match"); + return { start: { line: cursor.line, @@ -164,10 +164,10 @@ export class GenConSuggester extends EditorSuggest { const { language, linkType, createChapterLink } = this.plugin.settings; if (fullMatch === null) { - // console.log("getSuggestion didn't match"); + return []; } - // console.log(`getSuggestion matched: ${fullMatch}`); + const talk = fullMatch[0].replace(/^\:MC /, ""); @@ -177,7 +177,7 @@ export class GenConSuggester extends EditorSuggest { linkType, ); await suggestion.loadTalk(); - // console.log(`Suggestion: ${suggestion}`); + return [suggestion]; } diff --git a/src/translation.ts b/src/translation.ts deleted file mode 100644 index ff732c7..0000000 --- a/src/translation.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import * as zlib from "zlib"; -import * as tar from "tar"; -import { mkdir } from "fs/promises"; -import { Readable } from "stream"; - -import { requestUrl } from "obsidian"; -import envPaths from "./env-paths"; - -import { AvailableLanguage } from "./lang"; - -export async function installTranslation(pluginName: string, lang: AvailableLanguage) { - const paths = envPaths(pluginName); - const translationsDir = path.resolve(paths.config, "translations"); - const filename = `${lang}.tar.gz`; - const langdir = path.resolve(translationsDir, lang); - - if (!fs.existsSync(translationsDir)) - await mkdir(translationsDir, { recursive: true }); - - if (fs.existsSync(langdir)) { - console.info(`Translation already exists on ${langdir}.`); - return; - } - - const url = `https://raw.githubusercontent.com/pacokwon/lds-scripture-translations/build/${filename}`; - const response = await requestUrl(url); - const buffer = Buffer.from(response.arrayBuffer); - - const readstream = Readable.from(buffer); - const gunzip = zlib.createGunzip(); - const extract = tar.x({ - C: translationsDir, - }); - readstream.pipe(gunzip).pipe(extract); - - await new Promise((resolve, _reject) => { - extract.on("end", resolve); - }); -} diff --git a/src/ui/BookOfMormonSettingTab.ts b/src/ui/BookOfMormonSettingTab.ts index 5092112..af4a61f 100644 --- a/src/ui/BookOfMormonSettingTab.ts +++ b/src/ui/BookOfMormonSettingTab.ts @@ -66,7 +66,11 @@ export class BookOfMormonSettingTab extends PluginSettingTab { containerEl.createEl("h2", { text: "About" }); containerEl.createSpan({}, (span) => { - span.innerHTML = `Github`; + + span.createEl('a', { + href: 'https://github.com/ingiestein/obsidian-lds-scriptures-plugin', + text: 'Github'}); + }); } } diff --git a/src/utils/apiutils.ts b/src/utils/apiutils.ts index 0fe0aa0..af56e78 100644 --- a/src/utils/apiutils.ts +++ b/src/utils/apiutils.ts @@ -1,7 +1,5 @@ // Some of the following code is adapted from @epeters3 in his repository https://github.com/epeters3/gospel-search - - export function cheerioFind($: cheerio.Root, queries: any[]): cheerio.Cheerio | null { for (const query of queries) { const elements = $(query.name).filter((_, el) => { @@ -18,20 +16,14 @@ export function cheerioFind($: cheerio.Root, queries: any[]): cheerio.Cheerio | const genconregex = /https:\/\/www\.churchofjesuschrist\.org\/study(\/[\w-]+\/\d{4}\/\d{2}\/[\w-]+)/; const scriptureregex = /https:\/\/www\.churchofjesuschrist\.org\/study(\/[\w-]+\/[\w-]+\/[\w-]+\/[\w-]+)/; const match = url.match(genconregex) ? url.match(genconregex): url.match(scriptureregex)?url.match(scriptureregex):null ; - // console.log(`REGEX MATCH: ${match}`) + return match ? match[1] : null; } -// export function extractGenConURLPath(url: string): string | null { -// const regex = /https:\/\/www\.churchofjesuschrist\.org\/study(\/general-conference\/\d{4}\/\d{2}\/[\w-]+)/; -// const match = url.match(regex); -// console.log(`REGEX MATCH: ${match}`) -// return match ? match[1] : null; -// } export function buildAPIURL(lang:string,url:string){ let path = extractURLPath(url) - // console.log(`Path extracted: ${path}`) + return `https://www.churchofjesuschrist.org/study/api/v3/language-pages/type/content?lang=${lang}&uri=` + path; } diff --git a/src/utils/generalconference.ts b/src/utils/generalconference.ts index edf0f77..b6c4b0d 100644 --- a/src/utils/generalconference.ts +++ b/src/utils/generalconference.ts @@ -21,11 +21,7 @@ export async function fetchGenConTalk(url:string,method: 'GET' | 'POST' | 'PATCH throw new Error('This can only refernce talks from General Conference.'); } - var talkurl = buildAPIURL(lang,url) - - console.log(`Parsed Data from URL: `, parsedData); - console.log(`Starting AXIOS request of ${talkurl}`) - // const response = await axios.get(talkurl); + let talkurl = buildAPIURL(lang,url) const response = await requestUrl({ url: talkurl, @@ -34,7 +30,7 @@ export async function fetchGenConTalk(url:string,method: 'GET' | 'POST' | 'PATCH } }); if (response.status === 401 || response.status === 402) { - console.log(response.status); + return { title, author, @@ -55,32 +51,7 @@ export async function fetchGenConTalk(url:string,method: 'GET' | 'POST' | 'PATCH let authorrole = authorRoleElement ? authorRoleElement.text().trim() : "Author role not found"; author.push(authorname); author.push(authorrole); - console.log(`Athor array: ${author}`) - // let body = $(PARAGRAPHS_IN_BODY_QUERY.name).map((_, el) => $(el).text().trim()).get(); - // console.log(`Body?: ${body}`) - - // if (parsedData.paragraphs){ - // const {start,end} = parsedData.paragraphs; - // const paragraphEnd = end !== undefined ? end : start; - // content = body.slice(start-1, end); - // } - - - // title = $('#title1').text().trim(); - - // if (title.length === 0){ - // title = $('h1').first().text().trim(); - - - // // title = $('#p1').text().trim(); - // } - // // author = [$('#author1').text().trim(), $('#author2').text().trim()].filter(Boolean); - // // author = [$('#author-name').text().trim(), $('#author-role').text().trim()].filter(Boolean); - // author = [$('.author-name').text().trim(), $('.author-role').text().trim()].filter(Boolean); - // if (author.length === 0) { - // let author = [$('#author1').text().trim(), $('#author2').text().trim()].filter(Boolean); - // } if (parsedData.paragraphs) { const { start, end } = parsedData.paragraphs; const paragraphEnd = end !== undefined ? end : start; @@ -99,18 +70,10 @@ export async function fetchGenConTalk(url:string,method: 'GET' | 'POST' | 'PATCH month = parsedData.pathParts[3]; setting = "General Conference"; - console.log( - title, - author, - content, - year, - month, - setting - ) + if (!title || !content) { - console.log(`title error: ${title}`); - console.log(`content error: ${content}`); + throw new Error('Unable to extract the necessary data from the webpage.'); } diff --git a/src/utils/scripture.ts b/src/utils/scripture.ts index f50e0c3..c1061f1 100644 --- a/src/utils/scripture.ts +++ b/src/utils/scripture.ts @@ -13,14 +13,14 @@ export async function fetchScripture(url:string, method: 'GET' | 'POST' | 'PATCH let verses:Map = new Map(); let parsedData = parseURL(url); - console.log(`parsed scripture URL: ${parsedData.pathParts}, ${parsedData.queryParams.id}, ${parsedData.paragraphs?.start}, ${parsedData.paragraphs?.end}`); + let lang = parsedData.queryParams.lang ? parsedData.queryParams.lang : 'eng'; if (parsedData.pathParts[1] !== "scriptures"){ throw new Error('This can only refernce scripture verses.'); } - var apiurl = buildAPIURL(lang,url) - console.log(`Scripture api ulr: ${apiurl}`) + let apiurl = buildAPIURL(lang,url) + // request to API const response = await requestUrl({ @@ -30,7 +30,7 @@ export async function fetchScripture(url:string, method: 'GET' | 'POST' | 'PATCH }); if (response.status === 401 || response.status === 402) { - console.log(response.status); + return { book, chapter, @@ -43,7 +43,7 @@ try { const $ = cheerio.load(response.json["content"]["body"]); [book, chapter] = response.json["meta"]["title"].split(" "); in_language_book = response.json["meta"]["title"]; - console.log(`Book: ${book}, Chapter: ${chapter}`); + $(PARAGRAPHS_IN_BODY_QUERY.name).each((_, el) => { const id = $(el).attr('id'); if (id) { // Only include elements that have an ID @@ -51,23 +51,6 @@ try { } }); - - console.log(verses); - - - // if (parsedData.paragraphs) { - // const { start, end } = parsedData.paragraphs; - // const paragraphEnd = end !== undefined ? end : start; - - // for (let i = start; i <= paragraphEnd; i++) { - // const paragraph = $(`#p${i}`).text()?.trim(); - // if (paragraph) { - // content.push(paragraph); - // } else { - // console.warn(`Paragraph #${i} not found.`); - // } - // } - // } } diff --git a/src/utils/urlparsing.ts b/src/utils/urlparsing.ts index 687e39b..95398e2 100644 --- a/src/utils/urlparsing.ts +++ b/src/utils/urlparsing.ts @@ -18,7 +18,7 @@ interface ParsedURL { export function parseURL(url: string): ParsedURL { const parsedUrl = new URL(url); const pathParts = parsedUrl.pathname.split('/').filter(part => part); - console.log(pathParts); + const queryParams = queryString.parse(parsedUrl.search); let paragraphs;