From 24dfab154b3f7ba36cb13f72d413427d386b2876 Mon Sep 17 00:00:00 2001 From: Anthony Halim Date: Sun, 15 Oct 2023 09:39:01 +0800 Subject: [PATCH] feat: implement random query, feature request #19 (#21) --- .github/workflows/ci.yml | 10 +- lua/bible-verse/commands.lua | 88 +- lua/bible-verse/config/diatheke.lua | 8 +- lua/bible-verse/config/formatter.lua | 50 +- lua/bible-verse/config/highlighter.lua | 62 +- lua/bible-verse/config/init.lua | 64 +- lua/bible-verse/config/ui.lua | 168 +-- lua/bible-verse/core/diatheke.lua | 52 +- lua/bible-verse/core/highlight.lua | 87 +- lua/bible-verse/core/init.lua | 212 ++-- lua/bible-verse/core/ui.lua | 108 +- lua/bible-verse/core/verse.lua | 1400 ++++++++++++++++++++++ lua/bible-verse/formatter/bibleverse.lua | 68 +- lua/bible-verse/formatter/common.lua | 64 +- lua/bible-verse/formatter/init.lua | 44 +- lua/bible-verse/formatter/markdown.lua | 70 +- lua/bible-verse/formatter/plain.lua | 40 +- lua/bible-verse/health.lua | 76 +- lua/bible-verse/init.lua | 39 +- lua/bible-verse/utils/init.lua | 140 +-- 20 files changed, 2142 insertions(+), 708 deletions(-) create mode 100644 lua/bible-verse/core/verse.lua diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6af81bf..417ff66 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ jobs: tests: strategy: matrix: - neovim_version: ['nightly', 'v0.9.1'] + neovim_version: ['nightly', 'v0.9.1', 'v0.9.2', 'v0.9.4'] runs-on: ubuntu-latest @@ -24,10 +24,10 @@ jobs: sudo apt install -y libsword-utils diatheke export SWORD_PATH="/tmp/bibleverse/.sword" mkdir -p "${SWORD_PATH}/mods.d" - yes "yes" | installmgr -init - yes "yes" | installmgr -sc - yes "yes" | installmgr -r CrossWire - yes "yes" | installmgr -ri CrossWire KJV + yes "yes" 2>/dev/null | installmgr -init + yes "yes" 2>/dev/null | installmgr -sc + yes "yes" 2>/dev/null | installmgr -r CrossWire + yes "yes" 2>/dev/null | installmgr -ri CrossWire KJV - name: Run Tests run: | diff --git a/lua/bible-verse/commands.lua b/lua/bible-verse/commands.lua index 87cf24c..92c5fd6 100644 --- a/lua/bible-verse/commands.lua +++ b/lua/bible-verse/commands.lua @@ -11,57 +11,57 @@ M.commands = {} --- Execute command by name ---@param cmd? string command name function M.cmd(cmd) - if cmd and M.commands[cmd] then - M.commands[cmd]() - else - M.commands[Config.options.default_behaviour]() - end + if cmd and M.commands[cmd] then + M.commands[cmd]() + else + M.commands[Config.options.default_behaviour]() + end end function M.setup() - M.commands = { - query = function() - require("bible-verse.core").query_and_show() - end, - insert = function() - require("bible-verse.core").query_and_insert() - end, - } + M.commands = { + query = function() + require("bible-verse.core").query_and_show() + end, + insert = function() + require("bible-verse.core").query_and_insert() + end, + } - -- Check that config is sane - assert( - M.commands[Config.options.default_behaviour] ~= nil, - "unsupported default_behaviour|default_behaviour=" .. Config.options.default_behaviour - ) + -- Check that config is sane + assert( + M.commands[Config.options.default_behaviour] ~= nil, + "unsupported default_behaviour|default_behaviour=" .. Config.options.default_behaviour + ) - -- Main func - vim.api.nvim_create_user_command("BibleVerse", function(args) - local command = vim.trim(args.args or "") - M.cmd(command) - end, { - nargs = "?", - desc = "Query bible verses", - complete = function(_, line) - -- Completed word - if line:match("^%s*BibleVerse %w+ ") then - return {} - end + -- Main func + vim.api.nvim_create_user_command("BibleVerse", function(args) + local command = vim.trim(args.args or "") + M.cmd(command) + end, { + nargs = "?", + desc = "Query bible verses", + complete = function(_, line) + -- Completed word + if line:match("^%s*BibleVerse %w+ ") then + return {} + end - -- Midword - local prefix = line:match("^%s*BibleVerse (%w*)") or "" - return vim.tbl_filter(function(key) - return key:find(prefix) == 1 - end, vim.tbl_keys(M.commands)) - end, - }) + -- Midword + local prefix = line:match("^%s*BibleVerse (%w*)") or "" + return vim.tbl_filter(function(key) + return key:find(prefix) == 1 + end, vim.tbl_keys(M.commands)) + end, + }) - -- Sub funcs - for name in pairs(M.commands) do - local cmd = "BibleVerse" .. name:sub(1, 1):upper() .. name:sub(2) - vim.api.nvim_create_user_command(cmd, function() - M.cmd(name) - end, { desc = "BibleVerse " .. name }) - end + -- Sub funcs + for name in pairs(M.commands) do + local cmd = "BibleVerse" .. name:sub(1, 1):upper() .. name:sub(2) + vim.api.nvim_create_user_command(cmd, function() + M.cmd(name) + end, { desc = "BibleVerse " .. name }) + end end return M diff --git a/lua/bible-verse/config/diatheke.lua b/lua/bible-verse/config/diatheke.lua index 62ebd8d..aebff78 100644 --- a/lua/bible-verse/config/diatheke.lua +++ b/lua/bible-verse/config/diatheke.lua @@ -6,10 +6,10 @@ local M = {} ---@type BibleVerseDiathekeConfig M.defaults = { - -- (MANDATORY) translation: diatheke module to be used. - translation = "", - -- locale: locale as locales in the machine. - locale = "en", + -- (MANDATORY) translation: diatheke module to be used. + translation = "", + -- locale: locale as locales in the machine. + locale = "en", } return M diff --git a/lua/bible-verse/config/formatter.lua b/lua/bible-verse/config/formatter.lua index e274944..d29c914 100644 --- a/lua/bible-verse/config/formatter.lua +++ b/lua/bible-verse/config/formatter.lua @@ -20,31 +20,31 @@ local M = {} ---@type BibleVerseFmtConfig M.defaults = { - ---@type BibleVerseFmtMarkdownConfig - markdown = { - -- separator: text to be used as separator between chapters. Set to empty string to disable. - separator = "---", - -- quote_block: put the formatted text within a quote block. - quote_block = true, - -- omit_translation_footnote: omit translation name from the markdown text. - omit_translation_footnote = false, - }, - - ---@type BibleVerseFmtPlainConfig - plain = { - -- header_delimiter: text to be used to separate between the content of verse and the verse. - header_delimiter = " ", - -- omit_translation_footnote: omit translation name from the plain text. - omit_translation_footnote = true, - }, - - ---@type BibleVerseFmtBibleVerseConfig - bibleverse = { - -- separator: text to be used as separator between chapters. Set to empty string to disable. - separator = " ", - -- omit_translation_footnote: omit translation name from the BibleVerse text. - omit_translation_footnote = false, - }, + ---@type BibleVerseFmtMarkdownConfig + markdown = { + -- separator: text to be used as separator between chapters. Set to empty string to disable. + separator = "---", + -- quote_block: put the formatted text within a quote block. + quote_block = true, + -- omit_translation_footnote: omit translation name from the markdown text. + omit_translation_footnote = false, + }, + + ---@type BibleVerseFmtPlainConfig + plain = { + -- header_delimiter: text to be used to separate between the content of verse and the verse. + header_delimiter = " ", + -- omit_translation_footnote: omit translation name from the plain text. + omit_translation_footnote = true, + }, + + ---@type BibleVerseFmtBibleVerseConfig + bibleverse = { + -- separator: text to be used as separator between chapters. Set to empty string to disable. + separator = " ", + -- omit_translation_footnote: omit translation name from the BibleVerse text. + omit_translation_footnote = false, + }, } return M diff --git a/lua/bible-verse/config/highlighter.lua b/lua/bible-verse/config/highlighter.lua index 06a1c8f..40aade6 100644 --- a/lua/bible-verse/config/highlighter.lua +++ b/lua/bible-verse/config/highlighter.lua @@ -8,24 +8,24 @@ local M = {} ---@type BibleVerseHLConfig M.defaults = { - -- To see all highlight groups that are currently active, - -- :so $VIMRUNTIME/syntax/hitest.vim - -- see :h highlight + -- To see all highlight groups that are currently active, + -- :so $VIMRUNTIME/syntax/hitest.vim + -- see :h highlight - -- highlighting for bibleverse text - bibleverse = { - -- highlighting for book and chapter of the output e.g. John 1 - book_chapter = { - pattern = "", - hlgroup = "Title", -- Highlight group to use to highlight the text - }, - -- highlighting for verse number the output - verse_number = { pattern = "", hlgroup = "Number" }, - -- highlighting for translation used in the output - translation = { pattern = "", hlgroup = "ModeMsg" }, - -- highlighting for separator between book chapters used in the output - separator = { pattern = "", hlgroup = "NonText" }, - }, + -- highlighting for bibleverse text + bibleverse = { + -- highlighting for book and chapter of the output e.g. John 1 + book_chapter = { + pattern = "", + hlgroup = "Title", -- Highlight group to use to highlight the text + }, + -- highlighting for verse number the output + verse_number = { pattern = "", hlgroup = "Number" }, + -- highlighting for translation used in the output + translation = { pattern = "", hlgroup = "ModeMsg" }, + -- highlighting for separator between book chapters used in the output + separator = { pattern = "", hlgroup = "NonText" }, + }, } ---NOTE: pattern: must capture the following: @@ -36,20 +36,20 @@ M.defaults = { ---@type BibleVerseHLConfig ---@diagnostic disable:missing-fields M._default_override = { - bibleverse = { - book_chapter = { - pattern = "()bc{([%w ]+)}()", - }, - verse_number = { - pattern = "()vn{([%S]+)}()", - }, - translation = { - pattern = "()t{([%w ]+)}()", - }, - separator = { - pattern = "()sp{([%S ]+)}()", - }, - }, + bibleverse = { + book_chapter = { + pattern = "()bc{([%w ]+)}()", + }, + verse_number = { + pattern = "()vn{([%S]+)}()", + }, + translation = { + pattern = "()t{([%w ]+)}()", + }, + separator = { + pattern = "()sp{([%S ]+)}()", + }, + }, } return M diff --git a/lua/bible-verse/config/init.lua b/lua/bible-verse/config/init.lua index 0b6b854..1a261b6 100644 --- a/lua/bible-verse/config/init.lua +++ b/lua/bible-verse/config/init.lua @@ -13,28 +13,28 @@ local M = {} ---@type BibleVerseConfig M.defaults = { - -- default_behaviour: behaviour to be used on empty command arg, i.e. :BibleVerse. Defaults to query. - -- Options: "query" - on verse query, display the result on the screen as a popup. - -- "insert" - on verse query, insert the result below the cursor of the current buffer. - default_behaviour = "query", + -- default_behaviour: behaviour to be used on empty command arg, i.e. :BibleVerse. Defaults to query. + -- Options: "query" - on verse query, display the result on the screen as a popup. + -- "insert" - on verse query, insert the result below the cursor of the current buffer. + default_behaviour = "query", - -- query_format: text format on 'query' behaviour. - -- Options: "bibleverse" - query as bibleverse formatted text. - -- "plain" - query as plain text. - query_format = "bibleverse", + -- query_format: text format on 'query' behaviour. + -- Options: "bibleverse" - query as bibleverse formatted text. + -- "plain" - query as plain text. + query_format = "bibleverse", - -- insert_format: text format on 'insert' behaviour. - -- Options: "markdown" - insert as markdown formatted text. - -- "plain" - insert as plain text. - insert_format = "markdown", + -- insert_format: text format on 'insert' behaviour. + -- Options: "markdown" - insert as markdown formatted text. + -- "plain" - insert as plain text. + insert_format = "markdown", - -- Forbid plugin on the following buffer filetypes - exclude_buffer_filetypes = { "neo-tree", "NvimTree" }, + -- Forbid plugin on the following buffer filetypes + exclude_buffer_filetypes = { "neo-tree", "NvimTree" }, - diatheke = require("bible-verse.config.diatheke").defaults, - formatter = require("bible-verse.config.formatter").defaults, - highlighter = require("bible-verse.config.highlighter").defaults, - ui = require("bible-verse.config.ui").defaults, + diatheke = require("bible-verse.config.diatheke").defaults, + formatter = require("bible-verse.config.formatter").defaults, + highlighter = require("bible-verse.config.highlighter").defaults, + ui = require("bible-verse.config.ui").defaults, } ---@type BibleVerseConfig @@ -43,22 +43,22 @@ M.options = {} ---@param opts? table options to override. function M.setup(opts) - opts = opts or {} - M.options = vim.tbl_deep_extend("force", M.defaults, opts) - M.options.highlighter = - vim.tbl_deep_extend("force", M.options.highlighter, require("bible-verse.config.highlighter")._default_override) + opts = opts or {} + M.options = vim.tbl_deep_extend("force", M.defaults, opts) + M.options.highlighter = + vim.tbl_deep_extend("force", M.options.highlighter, require("bible-verse.config.highlighter")._default_override) - -- Assert config is sane - assert( - vim.tbl_contains({ "bibleverse", "plain" }, M.options.query_format), - "unsupported_opts|query_format=" .. M.options.query_format - ) - assert( - vim.tbl_contains({ "markdown", "plain" }, M.options.insert_format), - "unsupported_opts|insert_format=" .. M.options.insert_format - ) + -- Assert config is sane + assert( + vim.tbl_contains({ "bibleverse", "plain" }, M.options.query_format), + "unsupported_opts|query_format=" .. M.options.query_format + ) + assert( + vim.tbl_contains({ "markdown", "plain" }, M.options.insert_format), + "unsupported_opts|insert_format=" .. M.options.insert_format + ) - M.ns = vim.api.nvim_create_namespace("bible-verse-ns") + M.ns = vim.api.nvim_create_namespace("bible-verse-ns") end return M diff --git a/lua/bible-verse/config/ui.lua b/lua/bible-verse/config/ui.lua index 81b9934..283dc37 100644 --- a/lua/bible-verse/config/ui.lua +++ b/lua/bible-verse/config/ui.lua @@ -7,92 +7,92 @@ local M = {} ---@type BibleVerseUiConfig M.defaults = { - -- insert_input: configuration for input component for prompting input for 'insert' behaviour - -- see https://github.com/MunifTanjim/nui.nvim/tree/main/lua/nui/input - insert_input = { - enter = true, - focusable = true, - relative = "cursor", - border = { - style = "rounded", - padding = { 0, 1 }, - text = { - top = "Insert verse:", - top_align = "left", - }, - }, - win_options = { - winhighlight = "FloatBorder:FloatBorder", - }, - size = { - -- max_width: maximum width of the insert component, in number of cells - max_width = 50, -- custom attribute - height = 1, - }, - position = { - row = 1, - col = 0, - }, - zindex = 20, -- Must be > popup.zindex - }, + -- insert_input: configuration for input component for prompting input for 'insert' behaviour + -- see https://github.com/MunifTanjim/nui.nvim/tree/main/lua/nui/input + insert_input = { + enter = true, + focusable = true, + relative = "cursor", + border = { + style = "rounded", + padding = { 0, 1 }, + text = { + top = "Insert verse:", + top_align = "left", + }, + }, + win_options = { + winhighlight = "FloatBorder:FloatBorder", + }, + size = { + -- max_width: maximum width of the insert component, in number of cells + max_width = 50, -- custom attribute + height = 1, + }, + position = { + row = 1, + col = 0, + }, + zindex = 20, -- Must be > popup.zindex + }, - -- query_input: configuration for input component for prompting input for 'query' behaviour - -- see https://github.com/MunifTanjim/nui.nvim/tree/main/lua/nui/input - query_input = { - enter = true, - focusable = true, - relative = "editor", - border = { - style = "rounded", - padding = { 0, 1 }, - text = { - top = "Bible Verse", - top_align = "center", - }, - }, - size = { - max_width = 50, - height = 1, - }, - position = "50%", - zindex = 20, -- Must be > popup.zindex - win_options = { - winhighlight = "Normal:Normal,FloatBorder:FloatBorder", - }, - }, + -- query_input: configuration for input component for prompting input for 'query' behaviour + -- see https://github.com/MunifTanjim/nui.nvim/tree/main/lua/nui/input + query_input = { + enter = true, + focusable = true, + relative = "editor", + border = { + style = "rounded", + padding = { 0, 1 }, + text = { + top = "Bible Verse", + top_align = "center", + }, + }, + size = { + max_width = 50, + height = 1, + }, + position = "50%", + zindex = 20, -- Must be > popup.zindex + win_options = { + winhighlight = "Normal:Normal,FloatBorder:FloatBorder", + }, + }, - -- popup: configuration for popup component, extending from Nui configuration. - -- see: https://github.com/MunifTanjim/nui.nvim/tree/main/lua/nui/popup - popup = { - enter = true, - focusable = true, - relative = "editor", - border = { - style = "rounded", - padding = { 1, 1 }, - text = { - top = "Bible Verse", - top_align = "center", - }, - }, - size = { - -- width_percentage: % of current width used for the popup, in float. - -- max_width_percentage: maximum % of current width used for the popup, in float. - -- max_height_percentage: maximum % of current height used for the popup, in float. - width_percentage = 0.5, -- custom attribute - max_width_percentage = 0.8, -- custom attribute - max_height_percentage = 0.7, -- custom attribute - }, - position = "50%", - zindex = 10, - win_options = { - winhighlight = "Normal:Normal,FloatBorder:FloatBorder", - }, - buf_options = { - modifiable = false, - readonly = true, - }, - }, + -- popup: configuration for popup component, extending from Nui configuration. + -- see: https://github.com/MunifTanjim/nui.nvim/tree/main/lua/nui/popup + popup = { + enter = true, + focusable = true, + relative = "editor", + border = { + style = "rounded", + padding = { 1, 1 }, + text = { + top = "Bible Verse", + top_align = "center", + }, + }, + size = { + -- width_percentage: % of current width used for the popup, in float. + -- max_width_percentage: maximum % of current width used for the popup, in float. + -- max_height_percentage: maximum % of current height used for the popup, in float. + width_percentage = 0.5, -- custom attribute + max_width_percentage = 0.8, -- custom attribute + max_height_percentage = 0.7, -- custom attribute + }, + position = "50%", + zindex = 10, + win_options = { + winhighlight = "Normal:Normal,FloatBorder:FloatBorder", + }, + buf_options = { + modifiable = false, + readonly = true, + }, + }, } return M diff --git a/lua/bible-verse/core/diatheke.lua b/lua/bible-verse/core/diatheke.lua index 6fa45ef..79751bc 100644 --- a/lua/bible-verse/core/diatheke.lua +++ b/lua/bible-verse/core/diatheke.lua @@ -1,33 +1,25 @@ local M = {} ----@class DiathekeVerse ----@field book string ----@field chapter string ----@field verse_number string ----@field verse_prefix_newline boolean ----@field verse string ----@field verse_suffix_newline boolean - --- Parse raw diatheke output to the expected format. ---@param output string raw diatheke output ----@return DiathekeVerse[] verses +---@return Verse[] verses local function parse_raw_output(output) - local verses = {} + local verses = {} - _ = output:gsub("([%w ]+) ([%d]+):([%d]+):([%s]+)([^\r\n]+)[\r\n]", function(book, chap, vnum, prefix, v) - if book and chap and vnum and v then - table.insert(verses, { - book = book, - chapter = chap, - verse_number = vnum, - verse_prefix_newline = prefix and prefix:find("[\r\n]") ~= nil, - verse = v, - verse_suffix_newline = false, - }) - end - end) + _ = output:gsub("([%w ]+) ([%d]+):([%d]+):([%s]+)([^\r\n]+)[\r\n]", function(book, chap, vnum, prefix, v) + if book and chap and vnum and v then + table.insert(verses, { + book = book, + chapter = chap, + verse_number = vnum, + verse_prefix_newline = prefix and prefix:find("[\r\n]") ~= nil, + verse = v, + verse_suffix_newline = false, + }) + end + end) - return verses + return verses end --- Call diatheke CLI and return the parsed output. @@ -35,14 +27,14 @@ end ---@param format string output_format of diatheke; corresponds to -f flag of diatheke. e.g. plain, HTML ---@param locale string locale on the local machine. e.g. en ---@param query string query to diatheke. ----@return DiathekeVerse[] verses +---@return Verse[] verses function M.call(translation, format, locale, query) - local command = string.format("diatheke -b %s -f %s -l %s -k %s", translation, format, locale, query) - local command_output = vim.fn.system(command) - if vim.v.shell_error ~= 0 then - error("diatheke command return error|command=" .. command) - end - return parse_raw_output(command_output) + local command = string.format("diatheke -b %s -f %s -l %s -k %s", translation, format, locale, query) + local command_output = vim.fn.system(command) + if vim.v.shell_error ~= 0 then + error("diatheke command return error|command=" .. command) + end + return parse_raw_output(command_output) end return M diff --git a/lua/bible-verse/core/highlight.lua b/lua/bible-verse/core/highlight.lua index 46e58c6..dff5053 100644 --- a/lua/bible-verse/core/highlight.lua +++ b/lua/bible-verse/core/highlight.lua @@ -8,42 +8,57 @@ local M = {} ---@param first? integer ---@param last? integer function M.highlight_buf(bufnr, conf, first, last) - if conf == nil or not Utils.is_valid_buf(bufnr, Config.options.exclude_buffer_filetypes) then - return - end - - first = first or 0 - last = last or vim.api.nvim_buf_line_count(bufnr) - - vim.api.nvim_buf_clear_namespace(bufnr, Config.ns, first, last) - - local lines = vim.api.nvim_buf_get_lines(bufnr, first, last, false) - local replace_offset = 0 - - for l, line in ipairs(lines) do - replace_offset = 0 - - for _, settings in pairs(conf) do - -- NOTE: What about matching from the back so we don't have to deal with offsets? - line:gsub(settings.pattern, function(pattern_start_idx, word, pattern_end_idx) - local start_replace_from = pattern_start_idx - 1 + replace_offset - local start_replace_to = pattern_end_idx - 1 + replace_offset - - vim.api.nvim_buf_set_text(bufnr, l - 1, start_replace_from, l - 1, start_replace_to, { word }) - vim.api.nvim_buf_add_highlight( - bufnr, - Config.ns, - settings.hlgroup, - l - 1, - start_replace_from, - start_replace_from + #word - ) - - -- TODO: Add notes about the replace_offset magic - replace_offset = replace_offset + (#word - (pattern_end_idx - pattern_start_idx)) - end) - end - end + if conf == nil or not Utils.is_valid_buf(bufnr, Config.options.exclude_buffer_filetypes) then + return + end + + first = first or 0 + last = last or vim.api.nvim_buf_line_count(bufnr) + + vim.api.nvim_buf_clear_namespace(bufnr, Config.ns, first, last) + + local lines = vim.api.nvim_buf_get_lines(bufnr, first, last, false) + local replace_offset = 0 + + for l, line in ipairs(lines) do + replace_offset = 0 + + for _, settings in pairs(conf) do + line:gsub(settings.pattern, function(pattern_start_idx, word, pattern_end_idx) + local start_replace_from = pattern_start_idx - 1 + replace_offset + local start_replace_to = pattern_end_idx - 1 + replace_offset + + vim.api.nvim_buf_set_text(bufnr, l - 1, start_replace_from, l - 1, start_replace_to, { word }) + vim.api.nvim_buf_add_highlight( + bufnr, + Config.ns, + settings.hlgroup, + l - 1, + start_replace_from, + start_replace_from + #word + ) + + -- On every replacement, we need to offset to ensure match indexes are shifted + -- along with the replacement step. + -- + -- e.g. + -- 'I am b{first} match & b{second} match in the line' + -- -> First match: pattern_start_idx: 6, word: 'first', pattern_end_idx: 13 + -- -> Second match: pattern_start_idx: 23, wod: 'second', pattern_end_idx: 31 + -- + -- After first replacement on 'b{first}' with 'first', line is now: + -- 'I am first match & b{second} match in the line' + -- -> First match: pattern_start_idx: 6, word: 'first', pattern_end_idx: 13 + -- -> Second match: pattern_start_idx: 23, word: 'second', pattern_end_idx: 31 + -- + -- The second match match indexes are not updated and will point to the wrong index. + -- The offset required is defined as: + -- + -- accumulated_offset = previous_offset + length difference of matched pattern and replaced word + replace_offset = replace_offset + (#word - (pattern_end_idx - pattern_start_idx)) + end) + end + end end return M diff --git a/lua/bible-verse/core/init.lua b/lua/bible-verse/core/init.lua index 4e5d45f..49a64e5 100644 --- a/lua/bible-verse/core/init.lua +++ b/lua/bible-verse/core/init.lua @@ -1,113 +1,135 @@ local Config = require("bible-verse.config") local Formatter = require("bible-verse.formatter") - local Utils = require("bible-verse.utils") - local Diatheke = require("bible-verse.core.diatheke") +local VerseLib = require("bible-verse.core.verse") local Ui = require("bible-verse.core.ui") local Highlight = require("bible-verse.core.highlight") local M = {} ---- Process query within diatheke and return formatted output ----@param query string query to diatheke ----@param formatter_type FormatterType type of formatter to be used ----@param output_wrap_line_at number wrap output at given character length. Set to 0 to disable. ----@return string[] output table of individual lines of the output. -local function process_query(query, formatter_type, output_wrap_line_at) - local ok, res_or_err = - pcall(Diatheke.call, Config.options.diatheke.translation, "plain", Config.options.diatheke.locale, query) - if not ok then - error("query returned error|err=" .. res_or_err) - end - local output = Formatter.format(res_or_err, formatter_type) - return Utils.wrap(output, output_wrap_line_at) -end - function M.setup() - -- Check that config is sane - assert( - Config.options.diatheke.translation and string.len(Config.options.diatheke.translation) > 0, - "missing configuration|diatheke.translation" - ) + -- Check that config is sane + assert( + Config.options.diatheke.translation and string.len(Config.options.diatheke.translation) > 0, + "missing configuration|diatheke.translation" + ) end ---- Prompt for user input and show it back to the screen -function M.query_and_show() - -- Handle UI config - local input_conf = vim.deepcopy(Config.options.ui.query_input) - local relative_size = Utils.get_relative_size(input_conf.relative) - - local border_text_len = - math.max(string.len(input_conf.border.text.top or ""), string.len(input_conf.border.text.bottom or "")) - - input_conf.size.width = Utils.clamp(border_text_len, relative_size.width, input_conf.size.max_width) - - -- On submit function - local on_submit = function(input) - if input and string.len(input) > 0 then - local popup_conf = vim.deepcopy(Config.options.ui.popup) - relative_size = Utils.get_relative_size(popup_conf.relative) - - local popup_width = math.ceil( - math.min( - relative_size.width * popup_conf.size.max_width_percentage, - relative_size.width * popup_conf.size.width_percentage - ) - ) - local popup_max_height = math.ceil(relative_size.height * popup_conf.size.max_height_percentage) - - local query_result = process_query(input, Config.options.query_format, popup_width) - - popup_conf.size.width = popup_width - popup_conf.size.height = Utils.clamp(#query_result, 1, popup_max_height) - - Ui:popup(popup_conf, query_result, function(bufnr, first, last) - Highlight.highlight_buf(bufnr, Config.options.highlighter[Config.options.query_format], first, last) - end) - end - end +---@alias QueryOpts { query: string, random: boolean } + +--- Query the verse and return to the user. +---@param query_opt QueryOpts +---@return Verse[] result parsed output of the query +function M.query(query_opt) + local verse_query = query_opt.random and VerseLib.random_verse() or query_opt.query + local ok, res_or_err = + pcall(Diatheke.call, Config.options.diatheke.translation, "plain", Config.options.diatheke.locale, verse_query) + if not ok then + error("query returned error|err=" .. res_or_err) + end + return res_or_err +end - Ui:input(input_conf, on_submit) +--- Query the verse and show it back to the screen. If query is not provided, will prompt the user input. +---@param query_opt? QueryOpts +function M.query_and_show(query_opt) + query_opt = query_opt or { query = "", random = false } + + -- On submit function + local on_submit = function(input) + if input and string.len(input) > 0 then + local popup_conf = vim.deepcopy(Config.options.ui.popup) + local popup_relative_size = Utils.get_relative_size(popup_conf.relative) + + local popup_width = math.ceil( + math.min( + popup_relative_size.width * popup_conf.size.max_width_percentage, + popup_relative_size.width * popup_conf.size.width_percentage + ) + ) + local popup_max_height = math.ceil(popup_relative_size.height * popup_conf.size.max_height_percentage) + + local query_result = M.query({ query = input, random = false }) + local formatted_query_result = Formatter.format(query_result, Config.options.query_format) + local wrapped_query_result = Utils.wrap(formatted_query_result, popup_width) + + popup_conf.size.width = popup_width + popup_conf.size.height = Utils.clamp(#wrapped_query_result, 1, popup_max_height) + + Ui:popup(popup_conf, wrapped_query_result, function(bufnr, first, last) + Highlight.highlight_buf(bufnr, Config.options.highlighter[Config.options.query_format], first, last) + end) + end + end + + if query_opt.random then + -- Query random verse + on_submit(VerseLib.random_verse()) + elseif query_opt.query and #query_opt.query > 0 then + -- Handle user query directly + on_submit(query_opt.query) + else + -- Prompt for user input then query + local input_conf = vim.deepcopy(Config.options.ui.query_input) + local relative_size = Utils.get_relative_size(input_conf.relative) + local border_text_len = + math.max(string.len(input_conf.border.text.top or ""), string.len(input_conf.border.text.bottom or "")) + + input_conf.size.width = Utils.clamp(border_text_len, relative_size.width, input_conf.size.max_width) + + Ui:input(input_conf, on_submit) + end end ---- Prompt for user input and insert it below the cursor -function M.query_and_insert() - local cur_window_handler = vim.api.nvim_get_current_win() - if not Utils.is_valid_win(cur_window_handler) then - vim.notify("BibleVerse: invalid window to do insertion.", vim.log.levels.WARN) - return - end - - local cur_buf_handler = vim.api.nvim_win_get_buf(cur_window_handler) - if not Utils.is_valid_buf(cur_buf_handler, Config.options.exclude_buffer_filetypes) then - vim.notify( - "BibleVerse: invalid buffer to do insertion. Did you try to insert on wrong buffer?", - vim.log.levels.WARN - ) - return - end - - -- Handle UI config - local input_conf = vim.deepcopy(Config.options.ui.insert_input) - local relative_size = Utils.get_relative_size(input_conf.relative) - - local border_text_len = - math.max(string.len(input_conf.border.text.top or ""), string.len(input_conf.border.text.bottom or "")) - - input_conf.size.width = Utils.clamp(border_text_len, relative_size.width, input_conf.size.max_width) - - -- On submit function - local on_submit = function(input) - if input and string.len(input) > 0 then - local query_result = process_query(input, Config.options.insert_format, 0) - local row, _ = unpack(vim.api.nvim_win_get_cursor(cur_window_handler)) - - vim.api.nvim_buf_set_lines(cur_buf_handler, row - 1, row - 1, false, query_result) - end - end - - Ui:input(input_conf, on_submit) +--- Query the verse and insert it below the cursor. If query is not provided, will prompt the user input. +---@param query_opt? QueryOpts +function M.query_and_insert(query_opt) + query_opt = query_opt or { query = "", random = false } + + local cur_window_handler = vim.api.nvim_get_current_win() + if not Utils.is_valid_win(cur_window_handler) then + vim.notify("BibleVerse: invalid window to do insertion.", vim.log.levels.WARN) + return + end + + local cur_buf_handler = vim.api.nvim_win_get_buf(cur_window_handler) + if not Utils.is_valid_buf(cur_buf_handler, Config.options.exclude_buffer_filetypes) then + vim.notify( + "BibleVerse: invalid buffer to do insertion. Did you try to insert on wrong buffer?", + vim.log.levels.WARN + ) + return + end + + -- On submit function + local on_submit = function(input) + if input and string.len(input) > 0 then + local query_result = M.query({ query = input, random = false }) + local formatted_query_result = Formatter.format(query_result, Config.options.insert_format) + local row, _ = unpack(vim.api.nvim_win_get_cursor(cur_window_handler)) + + vim.api.nvim_buf_set_lines(cur_buf_handler, row - 1, row - 1, false, formatted_query_result) + end + end + + if query_opt.random then + -- Query random verse + on_submit(VerseLib.random_verse()) + elseif query_opt.query and #query_opt.query > 0 then + -- Handle user query directly + on_submit(query_opt.query) + else + -- Prompt for user input then query + local input_conf = vim.deepcopy(Config.options.ui.insert_input) + local relative_size = Utils.get_relative_size(input_conf.relative) + local border_text_len = + math.max(string.len(input_conf.border.text.top or ""), string.len(input_conf.border.text.bottom or "")) + + input_conf.size.width = Utils.clamp(border_text_len, relative_size.width, input_conf.size.max_width) + + Ui:input(input_conf, on_submit) + end end return M diff --git a/lua/bible-verse/core/ui.lua b/lua/bible-verse/core/ui.lua index 058d870..1e3cd0a 100644 --- a/lua/bible-verse/core/ui.lua +++ b/lua/bible-verse/core/ui.lua @@ -3,41 +3,41 @@ local NuiPopup = require("nui.popup") local NuiEvent = require("nui.utils.autocmd").event local M = { - input_ui = nil, - popup_ui = nil, + input_ui = nil, + popup_ui = nil, } ---Take user input and call on_submit on submission. ---@param config NuiInputOptions ---@param on_submit fun(input?: string): nil to execute on user submission function M:input(config, on_submit) - local cleanup = function() - if self.input_ui then - self.input_ui:unmount() - self.input_ui = nil - end - end + local cleanup = function() + if self.input_ui then + self.input_ui:unmount() + self.input_ui = nil + end + end - -- Cleanup previous instance, if any - cleanup() + -- Cleanup previous instance, if any + cleanup() - self.input_ui = NuiInput(config, { - prompt = "", -- Use prompt as border text - on_submit = function(input) - on_submit(input) - cleanup() - end, - }) + self.input_ui = NuiInput(config, { + prompt = "", -- Use prompt as border text + on_submit = function(input) + on_submit(input) + cleanup() + end, + }) - -- Set exit behaviour - self.input_ui:map("n", "", function() - cleanup() - end, { noremap = true }) - self.input_ui:on(NuiEvent.BufLeave, function() - cleanup() - end, { once = true }) + -- Set exit behaviour + self.input_ui:map("n", "", function() + cleanup() + end, { noremap = true }) + self.input_ui:on(NuiEvent.BufLeave, function() + cleanup() + end, { once = true }) - self.input_ui:mount() + self.input_ui:mount() end ---Show message as a pop up window. @@ -45,41 +45,41 @@ end ---@param message_table string[] table of individual lines to be shown. ---@param highlight_fn? fun(bufnr: integer, first?: integer, last?: integer): nil buffer highlighter. function M:popup(config, message_table, highlight_fn) - local cleanup = function() - if self.popup_ui then - self.popup_ui:unmount() - self.popup_ui = nil - end - end + local cleanup = function() + if self.popup_ui then + self.popup_ui:unmount() + self.popup_ui = nil + end + end - -- Cleanup previous instance, if any - cleanup() + -- Cleanup previous instance, if any + cleanup() - self.popup_ui = NuiPopup(config) + self.popup_ui = NuiPopup(config) - -- Set exit behaviour - self.popup_ui:map("n", "", function() - cleanup() - end, { noremap = true }) - self.popup_ui:map("n", "q", function() - cleanup() - end, { noremap = true }) - self.popup_ui:on(NuiEvent.BufLeave, function() - cleanup() - end, { once = true }) + -- Set exit behaviour + self.popup_ui:map("n", "", function() + cleanup() + end, { noremap = true }) + self.popup_ui:map("n", "q", function() + cleanup() + end, { noremap = true }) + self.popup_ui:on(NuiEvent.BufLeave, function() + cleanup() + end, { once = true }) - vim.api.nvim_buf_set_lines(self.popup_ui.bufnr, 0, 0, false, message_table) + vim.api.nvim_buf_set_lines(self.popup_ui.bufnr, 0, 0, false, message_table) - if highlight_fn then - -- NOTE: Once mounted, the popup may not be modifiable. We will not be able - -- to add highlight. Hence we highlight entire buffer before mounting. - -- PERF: Should be fine since we limit the buffer count to 1 (popup is kinda 'singleton') - local first = 0 - local last = vim.api.nvim_buf_line_count(self.popup_ui.bufnr) - highlight_fn(self.popup_ui.bufnr, first, last) - end + if highlight_fn then + -- NOTE: Once mounted, the popup may not be modifiable. We will not be able + -- to add highlight. Hence we highlight entire buffer before mounting. + -- PERF: Should be fine since we limit the buffer count to 1 (popup is kinda 'singleton') + local first = 0 + local last = vim.api.nvim_buf_line_count(self.popup_ui.bufnr) + highlight_fn(self.popup_ui.bufnr, first, last) + end - self.popup_ui:mount() + self.popup_ui:mount() end return M diff --git a/lua/bible-verse/core/verse.lua b/lua/bible-verse/core/verse.lua new file mode 100644 index 0000000..998ab02 --- /dev/null +++ b/lua/bible-verse/core/verse.lua @@ -0,0 +1,1400 @@ +local M = {} + +---@class Verse +---@field book string +---@field chapter string +---@field verse_number string +---@field verse_prefix_newline boolean +---@field verse string +---@field verse_suffix_newline boolean + +---@type table +local bible_data = { + ["1chronicles"] = { + { chapter = 1, max_verse = 54 }, + { chapter = 2, max_verse = 55 }, + { chapter = 3, max_verse = 24 }, + { chapter = 4, max_verse = 43 }, + { chapter = 5, max_verse = 26 }, + { chapter = 6, max_verse = 81 }, + { chapter = 7, max_verse = 40 }, + { chapter = 8, max_verse = 40 }, + { chapter = 9, max_verse = 44 }, + { chapter = 10, max_verse = 14 }, + { chapter = 11, max_verse = 47 }, + { chapter = 12, max_verse = 40 }, + { chapter = 13, max_verse = 14 }, + { chapter = 14, max_verse = 17 }, + { chapter = 15, max_verse = 29 }, + { chapter = 16, max_verse = 43 }, + { chapter = 17, max_verse = 27 }, + { chapter = 18, max_verse = 17 }, + { chapter = 19, max_verse = 19 }, + { chapter = 20, max_verse = 8 }, + { chapter = 21, max_verse = 30 }, + { chapter = 22, max_verse = 19 }, + { chapter = 23, max_verse = 32 }, + { chapter = 24, max_verse = 31 }, + { chapter = 25, max_verse = 31 }, + { chapter = 26, max_verse = 32 }, + { chapter = 27, max_verse = 34 }, + { chapter = 28, max_verse = 21 }, + { chapter = 29, max_verse = 30 }, + }, + ["1corinthians"] = { + { chapter = 1, max_verse = 31 }, + { chapter = 2, max_verse = 16 }, + { chapter = 3, max_verse = 23 }, + { chapter = 4, max_verse = 21 }, + { chapter = 5, max_verse = 13 }, + { chapter = 6, max_verse = 20 }, + { chapter = 7, max_verse = 40 }, + { chapter = 8, max_verse = 13 }, + { chapter = 9, max_verse = 27 }, + { chapter = 10, max_verse = 33 }, + { chapter = 11, max_verse = 34 }, + { chapter = 12, max_verse = 31 }, + { chapter = 13, max_verse = 13 }, + { chapter = 14, max_verse = 40 }, + { chapter = 15, max_verse = 58 }, + { chapter = 16, max_verse = 24 }, + }, + ["1john"] = { + { chapter = 1, max_verse = 10 }, + { chapter = 2, max_verse = 29 }, + { chapter = 3, max_verse = 24 }, + { chapter = 4, max_verse = 21 }, + { chapter = 5, max_verse = 21 }, + }, + ["1kings"] = { + { chapter = 1, max_verse = 53 }, + { chapter = 2, max_verse = 46 }, + { chapter = 3, max_verse = 28 }, + { chapter = 4, max_verse = 34 }, + { chapter = 5, max_verse = 18 }, + { chapter = 6, max_verse = 38 }, + { chapter = 7, max_verse = 51 }, + { chapter = 8, max_verse = 66 }, + { chapter = 9, max_verse = 28 }, + { chapter = 10, max_verse = 29 }, + { chapter = 11, max_verse = 43 }, + { chapter = 12, max_verse = 33 }, + { chapter = 13, max_verse = 34 }, + { chapter = 14, max_verse = 31 }, + { chapter = 15, max_verse = 34 }, + { chapter = 16, max_verse = 34 }, + { chapter = 17, max_verse = 24 }, + { chapter = 18, max_verse = 46 }, + { chapter = 19, max_verse = 21 }, + { chapter = 20, max_verse = 43 }, + { chapter = 21, max_verse = 29 }, + { chapter = 22, max_verse = 53 }, + }, + ["1peter"] = { + { chapter = 1, max_verse = 25 }, + { chapter = 2, max_verse = 25 }, + { chapter = 3, max_verse = 22 }, + { chapter = 4, max_verse = 19 }, + { chapter = 5, max_verse = 14 }, + }, + ["1samuel"] = { + { chapter = 1, max_verse = 28 }, + { chapter = 2, max_verse = 36 }, + { chapter = 3, max_verse = 21 }, + { chapter = 4, max_verse = 22 }, + { chapter = 5, max_verse = 12 }, + { chapter = 6, max_verse = 21 }, + { chapter = 7, max_verse = 17 }, + { chapter = 8, max_verse = 22 }, + { chapter = 9, max_verse = 27 }, + { chapter = 10, max_verse = 27 }, + { chapter = 11, max_verse = 15 }, + { chapter = 12, max_verse = 25 }, + { chapter = 13, max_verse = 23 }, + { chapter = 14, max_verse = 52 }, + { chapter = 15, max_verse = 35 }, + { chapter = 16, max_verse = 23 }, + { chapter = 17, max_verse = 58 }, + { chapter = 18, max_verse = 30 }, + { chapter = 19, max_verse = 24 }, + { chapter = 20, max_verse = 42 }, + { chapter = 21, max_verse = 15 }, + { chapter = 22, max_verse = 23 }, + { chapter = 23, max_verse = 29 }, + { chapter = 24, max_verse = 22 }, + { chapter = 25, max_verse = 44 }, + { chapter = 26, max_verse = 25 }, + { chapter = 27, max_verse = 12 }, + { chapter = 28, max_verse = 25 }, + { chapter = 29, max_verse = 11 }, + { chapter = 30, max_verse = 31 }, + { chapter = 31, max_verse = 13 }, + }, + ["1thessalonians"] = { + { chapter = 1, max_verse = 10 }, + { chapter = 2, max_verse = 20 }, + { chapter = 3, max_verse = 13 }, + { chapter = 4, max_verse = 18 }, + { chapter = 5, max_verse = 28 }, + }, + ["1timothy"] = { + { chapter = 1, max_verse = 20 }, + { chapter = 2, max_verse = 15 }, + { chapter = 3, max_verse = 16 }, + { chapter = 4, max_verse = 16 }, + { chapter = 5, max_verse = 25 }, + { chapter = 6, max_verse = 21 }, + }, + ["2chronicles"] = { + { chapter = 1, max_verse = 17 }, + { chapter = 2, max_verse = 18 }, + { chapter = 3, max_verse = 17 }, + { chapter = 4, max_verse = 22 }, + { chapter = 5, max_verse = 14 }, + { chapter = 6, max_verse = 42 }, + { chapter = 7, max_verse = 22 }, + { chapter = 8, max_verse = 18 }, + { chapter = 9, max_verse = 31 }, + { chapter = 10, max_verse = 19 }, + { chapter = 11, max_verse = 23 }, + { chapter = 12, max_verse = 16 }, + { chapter = 13, max_verse = 22 }, + { chapter = 14, max_verse = 15 }, + { chapter = 15, max_verse = 19 }, + { chapter = 16, max_verse = 14 }, + { chapter = 17, max_verse = 19 }, + { chapter = 18, max_verse = 34 }, + { chapter = 19, max_verse = 11 }, + { chapter = 20, max_verse = 37 }, + { chapter = 21, max_verse = 20 }, + { chapter = 22, max_verse = 12 }, + { chapter = 23, max_verse = 21 }, + { chapter = 24, max_verse = 27 }, + { chapter = 25, max_verse = 28 }, + { chapter = 26, max_verse = 23 }, + { chapter = 27, max_verse = 9 }, + { chapter = 28, max_verse = 27 }, + { chapter = 29, max_verse = 36 }, + { chapter = 30, max_verse = 27 }, + { chapter = 31, max_verse = 21 }, + { chapter = 32, max_verse = 33 }, + { chapter = 33, max_verse = 25 }, + { chapter = 34, max_verse = 33 }, + { chapter = 35, max_verse = 27 }, + { chapter = 36, max_verse = 23 }, + }, + ["2corinthians"] = { + { chapter = 1, max_verse = 24 }, + { chapter = 2, max_verse = 17 }, + { chapter = 3, max_verse = 18 }, + { chapter = 4, max_verse = 18 }, + { chapter = 5, max_verse = 21 }, + { chapter = 6, max_verse = 18 }, + { chapter = 7, max_verse = 16 }, + { chapter = 8, max_verse = 24 }, + { chapter = 9, max_verse = 15 }, + { chapter = 10, max_verse = 18 }, + { chapter = 11, max_verse = 33 }, + { chapter = 12, max_verse = 21 }, + { chapter = 13, max_verse = 14 }, + }, + ["2john"] = { { chapter = 1, max_verse = 13 } }, + ["2kings"] = { + { chapter = 1, max_verse = 18 }, + { chapter = 2, max_verse = 25 }, + { chapter = 3, max_verse = 27 }, + { chapter = 4, max_verse = 44 }, + { chapter = 5, max_verse = 27 }, + { chapter = 6, max_verse = 33 }, + { chapter = 7, max_verse = 20 }, + { chapter = 8, max_verse = 29 }, + { chapter = 9, max_verse = 37 }, + { chapter = 10, max_verse = 36 }, + { chapter = 11, max_verse = 21 }, + { chapter = 12, max_verse = 21 }, + { chapter = 13, max_verse = 25 }, + { chapter = 14, max_verse = 29 }, + { chapter = 15, max_verse = 38 }, + { chapter = 16, max_verse = 20 }, + { chapter = 17, max_verse = 41 }, + { chapter = 18, max_verse = 37 }, + { chapter = 19, max_verse = 37 }, + { chapter = 20, max_verse = 21 }, + { chapter = 21, max_verse = 26 }, + { chapter = 22, max_verse = 20 }, + { chapter = 23, max_verse = 37 }, + { chapter = 24, max_verse = 20 }, + { chapter = 25, max_verse = 30 }, + }, + ["2peter"] = { + { chapter = 1, max_verse = 21 }, + { chapter = 2, max_verse = 22 }, + { chapter = 3, max_verse = 18 }, + }, + ["2samuel"] = { + { chapter = 1, max_verse = 27 }, + { chapter = 2, max_verse = 32 }, + { chapter = 3, max_verse = 39 }, + { chapter = 4, max_verse = 12 }, + { chapter = 5, max_verse = 25 }, + { chapter = 6, max_verse = 23 }, + { chapter = 7, max_verse = 29 }, + { chapter = 8, max_verse = 18 }, + { chapter = 9, max_verse = 13 }, + { chapter = 10, max_verse = 19 }, + { chapter = 11, max_verse = 27 }, + { chapter = 12, max_verse = 31 }, + { chapter = 13, max_verse = 39 }, + { chapter = 14, max_verse = 33 }, + { chapter = 15, max_verse = 37 }, + { chapter = 16, max_verse = 23 }, + { chapter = 17, max_verse = 29 }, + { chapter = 18, max_verse = 33 }, + { chapter = 19, max_verse = 43 }, + { chapter = 20, max_verse = 26 }, + { chapter = 21, max_verse = 22 }, + { chapter = 22, max_verse = 51 }, + { chapter = 23, max_verse = 39 }, + { chapter = 24, max_verse = 25 }, + }, + ["2thessalonians"] = { + { chapter = 1, max_verse = 12 }, + { chapter = 2, max_verse = 17 }, + { chapter = 3, max_verse = 18 }, + }, + ["2timothy"] = { + { chapter = 1, max_verse = 18 }, + { chapter = 2, max_verse = 26 }, + { chapter = 3, max_verse = 17 }, + { chapter = 4, max_verse = 22 }, + }, + ["3john"] = { { chapter = 1, max_verse = 14 } }, + acts = { + { chapter = 1, max_verse = 26 }, + { chapter = 2, max_verse = 47 }, + { chapter = 3, max_verse = 26 }, + { chapter = 4, max_verse = 37 }, + { chapter = 5, max_verse = 42 }, + { chapter = 6, max_verse = 15 }, + { chapter = 7, max_verse = 60 }, + { chapter = 8, max_verse = 40 }, + { chapter = 9, max_verse = 43 }, + { chapter = 10, max_verse = 48 }, + { chapter = 11, max_verse = 30 }, + { chapter = 12, max_verse = 25 }, + { chapter = 13, max_verse = 52 }, + { chapter = 14, max_verse = 28 }, + { chapter = 15, max_verse = 41 }, + { chapter = 16, max_verse = 40 }, + { chapter = 17, max_verse = 34 }, + { chapter = 18, max_verse = 28 }, + { chapter = 19, max_verse = 41 }, + { chapter = 20, max_verse = 38 }, + { chapter = 21, max_verse = 40 }, + { chapter = 22, max_verse = 30 }, + { chapter = 23, max_verse = 35 }, + { chapter = 24, max_verse = 27 }, + { chapter = 25, max_verse = 27 }, + { chapter = 26, max_verse = 32 }, + { chapter = 27, max_verse = 44 }, + { chapter = 28, max_verse = 31 }, + }, + amos = { + { chapter = 1, max_verse = 15 }, + { chapter = 2, max_verse = 16 }, + { chapter = 3, max_verse = 15 }, + { chapter = 4, max_verse = 13 }, + { chapter = 5, max_verse = 27 }, + { chapter = 6, max_verse = 14 }, + { chapter = 7, max_verse = 17 }, + { chapter = 8, max_verse = 14 }, + { chapter = 9, max_verse = 15 }, + }, + colossians = { + { chapter = 1, max_verse = 29 }, + { chapter = 2, max_verse = 23 }, + { chapter = 3, max_verse = 25 }, + { chapter = 4, max_verse = 18 }, + }, + daniel = { + { chapter = 1, max_verse = 21 }, + { chapter = 2, max_verse = 49 }, + { chapter = 3, max_verse = 30 }, + { chapter = 4, max_verse = 37 }, + { chapter = 5, max_verse = 31 }, + { chapter = 6, max_verse = 28 }, + { chapter = 7, max_verse = 28 }, + { chapter = 8, max_verse = 27 }, + { chapter = 9, max_verse = 27 }, + { chapter = 10, max_verse = 21 }, + { chapter = 11, max_verse = 45 }, + { chapter = 12, max_verse = 13 }, + }, + deuteronomy = { + { chapter = 1, max_verse = 46 }, + { chapter = 2, max_verse = 37 }, + { chapter = 3, max_verse = 29 }, + { chapter = 4, max_verse = 49 }, + { chapter = 5, max_verse = 33 }, + { chapter = 6, max_verse = 25 }, + { chapter = 7, max_verse = 26 }, + { chapter = 8, max_verse = 20 }, + { chapter = 9, max_verse = 29 }, + { chapter = 10, max_verse = 22 }, + { chapter = 11, max_verse = 32 }, + { chapter = 12, max_verse = 32 }, + { chapter = 13, max_verse = 18 }, + { chapter = 14, max_verse = 29 }, + { chapter = 15, max_verse = 23 }, + { chapter = 16, max_verse = 22 }, + { chapter = 17, max_verse = 20 }, + { chapter = 18, max_verse = 22 }, + { chapter = 19, max_verse = 21 }, + { chapter = 20, max_verse = 20 }, + { chapter = 21, max_verse = 23 }, + { chapter = 22, max_verse = 30 }, + { chapter = 23, max_verse = 25 }, + { chapter = 24, max_verse = 22 }, + { chapter = 25, max_verse = 19 }, + { chapter = 26, max_verse = 19 }, + { chapter = 27, max_verse = 26 }, + { chapter = 28, max_verse = 68 }, + { chapter = 29, max_verse = 29 }, + { chapter = 30, max_verse = 20 }, + { chapter = 31, max_verse = 30 }, + { chapter = 32, max_verse = 52 }, + { chapter = 33, max_verse = 29 }, + { chapter = 34, max_verse = 12 }, + }, + ecclesiastes = { + { chapter = 1, max_verse = 18 }, + { chapter = 2, max_verse = 26 }, + { chapter = 3, max_verse = 22 }, + { chapter = 4, max_verse = 16 }, + { chapter = 5, max_verse = 20 }, + { chapter = 6, max_verse = 12 }, + { chapter = 7, max_verse = 29 }, + { chapter = 8, max_verse = 17 }, + { chapter = 9, max_verse = 18 }, + { chapter = 10, max_verse = 20 }, + { chapter = 11, max_verse = 10 }, + { chapter = 12, max_verse = 14 }, + }, + ephesians = { + { chapter = 1, max_verse = 23 }, + { chapter = 2, max_verse = 22 }, + { chapter = 3, max_verse = 21 }, + { chapter = 4, max_verse = 32 }, + { chapter = 5, max_verse = 33 }, + { chapter = 6, max_verse = 24 }, + }, + esther = { + { chapter = 1, max_verse = 22 }, + { chapter = 2, max_verse = 23 }, + { chapter = 3, max_verse = 15 }, + { chapter = 4, max_verse = 17 }, + { chapter = 5, max_verse = 14 }, + { chapter = 6, max_verse = 14 }, + { chapter = 7, max_verse = 10 }, + { chapter = 8, max_verse = 17 }, + { chapter = 9, max_verse = 32 }, + { chapter = 10, max_verse = 3 }, + }, + exodus = { + { chapter = 1, max_verse = 22 }, + { chapter = 2, max_verse = 25 }, + { chapter = 3, max_verse = 22 }, + { chapter = 4, max_verse = 31 }, + { chapter = 5, max_verse = 23 }, + { chapter = 6, max_verse = 30 }, + { chapter = 7, max_verse = 25 }, + { chapter = 8, max_verse = 32 }, + { chapter = 9, max_verse = 35 }, + { chapter = 10, max_verse = 29 }, + { chapter = 11, max_verse = 10 }, + { chapter = 12, max_verse = 51 }, + { chapter = 13, max_verse = 22 }, + { chapter = 14, max_verse = 31 }, + { chapter = 15, max_verse = 27 }, + { chapter = 16, max_verse = 36 }, + { chapter = 17, max_verse = 16 }, + { chapter = 18, max_verse = 27 }, + { chapter = 19, max_verse = 25 }, + { chapter = 20, max_verse = 26 }, + { chapter = 21, max_verse = 36 }, + { chapter = 22, max_verse = 31 }, + { chapter = 23, max_verse = 33 }, + { chapter = 24, max_verse = 18 }, + { chapter = 25, max_verse = 40 }, + { chapter = 26, max_verse = 37 }, + { chapter = 27, max_verse = 21 }, + { chapter = 28, max_verse = 43 }, + { chapter = 29, max_verse = 46 }, + { chapter = 30, max_verse = 38 }, + { chapter = 31, max_verse = 18 }, + { chapter = 32, max_verse = 35 }, + { chapter = 33, max_verse = 23 }, + { chapter = 34, max_verse = 35 }, + { chapter = 35, max_verse = 35 }, + { chapter = 36, max_verse = 38 }, + { chapter = 37, max_verse = 29 }, + { chapter = 38, max_verse = 31 }, + { chapter = 39, max_verse = 43 }, + { chapter = 40, max_verse = 38 }, + }, + ezekiel = { + { chapter = 1, max_verse = 28 }, + { chapter = 2, max_verse = 10 }, + { chapter = 3, max_verse = 27 }, + { chapter = 4, max_verse = 17 }, + { chapter = 5, max_verse = 17 }, + { chapter = 6, max_verse = 14 }, + { chapter = 7, max_verse = 27 }, + { chapter = 8, max_verse = 18 }, + { chapter = 9, max_verse = 11 }, + { chapter = 10, max_verse = 22 }, + { chapter = 11, max_verse = 25 }, + { chapter = 12, max_verse = 28 }, + { chapter = 13, max_verse = 23 }, + { chapter = 14, max_verse = 23 }, + { chapter = 15, max_verse = 8 }, + { chapter = 16, max_verse = 63 }, + { chapter = 17, max_verse = 24 }, + { chapter = 18, max_verse = 32 }, + { chapter = 19, max_verse = 14 }, + { chapter = 20, max_verse = 49 }, + { chapter = 21, max_verse = 32 }, + { chapter = 22, max_verse = 31 }, + { chapter = 23, max_verse = 49 }, + { chapter = 24, max_verse = 27 }, + { chapter = 25, max_verse = 17 }, + { chapter = 26, max_verse = 21 }, + { chapter = 27, max_verse = 36 }, + { chapter = 28, max_verse = 26 }, + { chapter = 29, max_verse = 21 }, + { chapter = 30, max_verse = 26 }, + { chapter = 31, max_verse = 18 }, + { chapter = 32, max_verse = 32 }, + { chapter = 33, max_verse = 33 }, + { chapter = 34, max_verse = 31 }, + { chapter = 35, max_verse = 15 }, + { chapter = 36, max_verse = 38 }, + { chapter = 37, max_verse = 28 }, + { chapter = 38, max_verse = 23 }, + { chapter = 39, max_verse = 29 }, + { chapter = 40, max_verse = 49 }, + { chapter = 41, max_verse = 26 }, + { chapter = 42, max_verse = 20 }, + { chapter = 43, max_verse = 27 }, + { chapter = 44, max_verse = 31 }, + { chapter = 45, max_verse = 25 }, + { chapter = 46, max_verse = 24 }, + { chapter = 47, max_verse = 23 }, + { chapter = 48, max_verse = 35 }, + }, + ezra = { + { chapter = 1, max_verse = 11 }, + { chapter = 2, max_verse = 70 }, + { chapter = 3, max_verse = 13 }, + { chapter = 4, max_verse = 24 }, + { chapter = 5, max_verse = 17 }, + { chapter = 6, max_verse = 22 }, + { chapter = 7, max_verse = 28 }, + { chapter = 8, max_verse = 36 }, + { chapter = 9, max_verse = 15 }, + { chapter = 10, max_verse = 44 }, + }, + galatians = { + { chapter = 1, max_verse = 24 }, + { chapter = 2, max_verse = 21 }, + { chapter = 3, max_verse = 29 }, + { chapter = 4, max_verse = 31 }, + { chapter = 5, max_verse = 26 }, + { chapter = 6, max_verse = 18 }, + }, + genesis = { + { chapter = 1, max_verse = 31 }, + { chapter = 2, max_verse = 25 }, + { chapter = 3, max_verse = 24 }, + { chapter = 4, max_verse = 26 }, + { chapter = 5, max_verse = 32 }, + { chapter = 6, max_verse = 22 }, + { chapter = 7, max_verse = 24 }, + { chapter = 8, max_verse = 22 }, + { chapter = 9, max_verse = 29 }, + { chapter = 10, max_verse = 32 }, + { chapter = 11, max_verse = 32 }, + { chapter = 12, max_verse = 20 }, + { chapter = 13, max_verse = 18 }, + { chapter = 14, max_verse = 24 }, + { chapter = 15, max_verse = 21 }, + { chapter = 16, max_verse = 16 }, + { chapter = 17, max_verse = 27 }, + { chapter = 18, max_verse = 33 }, + { chapter = 19, max_verse = 38 }, + { chapter = 20, max_verse = 18 }, + { chapter = 21, max_verse = 34 }, + { chapter = 22, max_verse = 24 }, + { chapter = 23, max_verse = 20 }, + { chapter = 24, max_verse = 67 }, + { chapter = 25, max_verse = 34 }, + { chapter = 26, max_verse = 35 }, + { chapter = 27, max_verse = 46 }, + { chapter = 28, max_verse = 22 }, + { chapter = 29, max_verse = 35 }, + { chapter = 30, max_verse = 43 }, + { chapter = 31, max_verse = 55 }, + { chapter = 32, max_verse = 32 }, + { chapter = 33, max_verse = 20 }, + { chapter = 34, max_verse = 31 }, + { chapter = 35, max_verse = 29 }, + { chapter = 36, max_verse = 43 }, + { chapter = 37, max_verse = 36 }, + { chapter = 38, max_verse = 30 }, + { chapter = 39, max_verse = 23 }, + { chapter = 40, max_verse = 23 }, + { chapter = 41, max_verse = 57 }, + { chapter = 42, max_verse = 38 }, + { chapter = 43, max_verse = 34 }, + { chapter = 44, max_verse = 34 }, + { chapter = 45, max_verse = 28 }, + { chapter = 46, max_verse = 34 }, + { chapter = 47, max_verse = 31 }, + { chapter = 48, max_verse = 22 }, + { chapter = 49, max_verse = 33 }, + { chapter = 50, max_verse = 26 }, + }, + habakkuk = { + { chapter = 1, max_verse = 17 }, + { chapter = 2, max_verse = 20 }, + { chapter = 3, max_verse = 19 }, + }, + haggai = { { chapter = 1, max_verse = 15 }, { chapter = 2, max_verse = 23 } }, + hebrews = { + { chapter = 1, max_verse = 14 }, + { chapter = 2, max_verse = 18 }, + { chapter = 3, max_verse = 19 }, + { chapter = 4, max_verse = 16 }, + { chapter = 5, max_verse = 14 }, + { chapter = 6, max_verse = 20 }, + { chapter = 7, max_verse = 28 }, + { chapter = 8, max_verse = 13 }, + { chapter = 9, max_verse = 28 }, + { chapter = 10, max_verse = 39 }, + { chapter = 11, max_verse = 40 }, + { chapter = 12, max_verse = 29 }, + { chapter = 13, max_verse = 25 }, + }, + hosea = { + { chapter = 1, max_verse = 11 }, + { chapter = 2, max_verse = 23 }, + { chapter = 3, max_verse = 5 }, + { chapter = 4, max_verse = 19 }, + { chapter = 5, max_verse = 15 }, + { chapter = 6, max_verse = 11 }, + { chapter = 7, max_verse = 16 }, + { chapter = 8, max_verse = 14 }, + { chapter = 9, max_verse = 17 }, + { chapter = 10, max_verse = 15 }, + { chapter = 11, max_verse = 12 }, + { chapter = 12, max_verse = 14 }, + { chapter = 13, max_verse = 16 }, + { chapter = 14, max_verse = 9 }, + }, + isaiah = { + { chapter = 1, max_verse = 31 }, + { chapter = 2, max_verse = 22 }, + { chapter = 3, max_verse = 26 }, + { chapter = 4, max_verse = 6 }, + { chapter = 5, max_verse = 30 }, + { chapter = 6, max_verse = 13 }, + { chapter = 7, max_verse = 25 }, + { chapter = 8, max_verse = 22 }, + { chapter = 9, max_verse = 21 }, + { chapter = 10, max_verse = 34 }, + { chapter = 11, max_verse = 16 }, + { chapter = 12, max_verse = 6 }, + { chapter = 13, max_verse = 22 }, + { chapter = 14, max_verse = 32 }, + { chapter = 15, max_verse = 9 }, + { chapter = 16, max_verse = 14 }, + { chapter = 17, max_verse = 14 }, + { chapter = 18, max_verse = 7 }, + { chapter = 19, max_verse = 25 }, + { chapter = 20, max_verse = 6 }, + { chapter = 21, max_verse = 17 }, + { chapter = 22, max_verse = 25 }, + { chapter = 23, max_verse = 18 }, + { chapter = 24, max_verse = 23 }, + { chapter = 25, max_verse = 12 }, + { chapter = 26, max_verse = 21 }, + { chapter = 27, max_verse = 13 }, + { chapter = 28, max_verse = 29 }, + { chapter = 29, max_verse = 24 }, + { chapter = 30, max_verse = 33 }, + { chapter = 31, max_verse = 9 }, + { chapter = 32, max_verse = 20 }, + { chapter = 33, max_verse = 24 }, + { chapter = 34, max_verse = 17 }, + { chapter = 35, max_verse = 10 }, + { chapter = 36, max_verse = 22 }, + { chapter = 37, max_verse = 38 }, + { chapter = 38, max_verse = 22 }, + { chapter = 39, max_verse = 8 }, + { chapter = 40, max_verse = 31 }, + { chapter = 41, max_verse = 29 }, + { chapter = 42, max_verse = 25 }, + { chapter = 43, max_verse = 28 }, + { chapter = 44, max_verse = 28 }, + { chapter = 45, max_verse = 25 }, + { chapter = 46, max_verse = 13 }, + { chapter = 47, max_verse = 15 }, + { chapter = 48, max_verse = 22 }, + { chapter = 49, max_verse = 26 }, + { chapter = 50, max_verse = 11 }, + { chapter = 51, max_verse = 23 }, + { chapter = 52, max_verse = 15 }, + { chapter = 53, max_verse = 12 }, + { chapter = 54, max_verse = 17 }, + { chapter = 55, max_verse = 13 }, + { chapter = 56, max_verse = 12 }, + { chapter = 57, max_verse = 21 }, + { chapter = 58, max_verse = 14 }, + { chapter = 59, max_verse = 21 }, + { chapter = 60, max_verse = 22 }, + { chapter = 61, max_verse = 11 }, + { chapter = 62, max_verse = 12 }, + { chapter = 63, max_verse = 19 }, + { chapter = 64, max_verse = 12 }, + { chapter = 65, max_verse = 25 }, + { chapter = 66, max_verse = 24 }, + }, + james = { + { chapter = 1, max_verse = 27 }, + { chapter = 2, max_verse = 26 }, + { chapter = 3, max_verse = 18 }, + { chapter = 4, max_verse = 17 }, + { chapter = 5, max_verse = 20 }, + }, + jeremiah = { + { chapter = 1, max_verse = 19 }, + { chapter = 2, max_verse = 37 }, + { chapter = 3, max_verse = 25 }, + { chapter = 4, max_verse = 31 }, + { chapter = 5, max_verse = 31 }, + { chapter = 6, max_verse = 30 }, + { chapter = 7, max_verse = 34 }, + { chapter = 8, max_verse = 22 }, + { chapter = 9, max_verse = 26 }, + { chapter = 10, max_verse = 25 }, + { chapter = 11, max_verse = 23 }, + { chapter = 12, max_verse = 17 }, + { chapter = 13, max_verse = 27 }, + { chapter = 14, max_verse = 22 }, + { chapter = 15, max_verse = 21 }, + { chapter = 16, max_verse = 21 }, + { chapter = 17, max_verse = 27 }, + { chapter = 18, max_verse = 23 }, + { chapter = 19, max_verse = 15 }, + { chapter = 20, max_verse = 18 }, + { chapter = 21, max_verse = 14 }, + { chapter = 22, max_verse = 30 }, + { chapter = 23, max_verse = 40 }, + { chapter = 24, max_verse = 10 }, + { chapter = 25, max_verse = 38 }, + { chapter = 26, max_verse = 24 }, + { chapter = 27, max_verse = 22 }, + { chapter = 28, max_verse = 17 }, + { chapter = 29, max_verse = 32 }, + { chapter = 30, max_verse = 24 }, + { chapter = 31, max_verse = 40 }, + { chapter = 32, max_verse = 44 }, + { chapter = 33, max_verse = 26 }, + { chapter = 34, max_verse = 22 }, + { chapter = 35, max_verse = 19 }, + { chapter = 36, max_verse = 32 }, + { chapter = 37, max_verse = 21 }, + { chapter = 38, max_verse = 28 }, + { chapter = 39, max_verse = 18 }, + { chapter = 40, max_verse = 16 }, + { chapter = 41, max_verse = 18 }, + { chapter = 42, max_verse = 22 }, + { chapter = 43, max_verse = 13 }, + { chapter = 44, max_verse = 30 }, + { chapter = 45, max_verse = 5 }, + { chapter = 46, max_verse = 28 }, + { chapter = 47, max_verse = 7 }, + { chapter = 48, max_verse = 47 }, + { chapter = 49, max_verse = 39 }, + { chapter = 50, max_verse = 46 }, + { chapter = 51, max_verse = 64 }, + { chapter = 52, max_verse = 34 }, + }, + job = { + { chapter = 1, max_verse = 22 }, + { chapter = 2, max_verse = 13 }, + { chapter = 3, max_verse = 26 }, + { chapter = 4, max_verse = 21 }, + { chapter = 5, max_verse = 27 }, + { chapter = 6, max_verse = 30 }, + { chapter = 7, max_verse = 21 }, + { chapter = 8, max_verse = 22 }, + { chapter = 9, max_verse = 35 }, + { chapter = 10, max_verse = 22 }, + { chapter = 11, max_verse = 20 }, + { chapter = 12, max_verse = 25 }, + { chapter = 13, max_verse = 28 }, + { chapter = 14, max_verse = 22 }, + { chapter = 15, max_verse = 35 }, + { chapter = 16, max_verse = 22 }, + { chapter = 17, max_verse = 16 }, + { chapter = 18, max_verse = 21 }, + { chapter = 19, max_verse = 29 }, + { chapter = 20, max_verse = 29 }, + { chapter = 21, max_verse = 34 }, + { chapter = 22, max_verse = 30 }, + { chapter = 23, max_verse = 17 }, + { chapter = 24, max_verse = 25 }, + { chapter = 25, max_verse = 6 }, + { chapter = 26, max_verse = 14 }, + { chapter = 27, max_verse = 23 }, + { chapter = 28, max_verse = 28 }, + { chapter = 29, max_verse = 25 }, + { chapter = 30, max_verse = 31 }, + { chapter = 31, max_verse = 40 }, + { chapter = 32, max_verse = 22 }, + { chapter = 33, max_verse = 33 }, + { chapter = 34, max_verse = 37 }, + { chapter = 35, max_verse = 16 }, + { chapter = 36, max_verse = 33 }, + { chapter = 37, max_verse = 24 }, + { chapter = 38, max_verse = 41 }, + { chapter = 39, max_verse = 30 }, + { chapter = 40, max_verse = 24 }, + { chapter = 41, max_verse = 34 }, + { chapter = 42, max_verse = 17 }, + }, + joel = { + { chapter = 1, max_verse = 20 }, + { chapter = 2, max_verse = 32 }, + { chapter = 3, max_verse = 21 }, + }, + john = { + { chapter = 1, max_verse = 51 }, + { chapter = 2, max_verse = 25 }, + { chapter = 3, max_verse = 36 }, + { chapter = 4, max_verse = 54 }, + { chapter = 5, max_verse = 47 }, + { chapter = 6, max_verse = 71 }, + { chapter = 7, max_verse = 53 }, + { chapter = 8, max_verse = 59 }, + { chapter = 9, max_verse = 41 }, + { chapter = 10, max_verse = 42 }, + { chapter = 11, max_verse = 57 }, + { chapter = 12, max_verse = 50 }, + { chapter = 13, max_verse = 38 }, + { chapter = 14, max_verse = 31 }, + { chapter = 15, max_verse = 27 }, + { chapter = 16, max_verse = 33 }, + { chapter = 17, max_verse = 26 }, + { chapter = 18, max_verse = 40 }, + { chapter = 19, max_verse = 42 }, + { chapter = 20, max_verse = 31 }, + { chapter = 21, max_verse = 25 }, + }, + jonah = { + { chapter = 1, max_verse = 17 }, + { chapter = 2, max_verse = 10 }, + { chapter = 3, max_verse = 10 }, + { chapter = 4, max_verse = 11 }, + }, + joshua = { + { chapter = 1, max_verse = 18 }, + { chapter = 2, max_verse = 24 }, + { chapter = 3, max_verse = 17 }, + { chapter = 4, max_verse = 24 }, + { chapter = 5, max_verse = 15 }, + { chapter = 6, max_verse = 27 }, + { chapter = 7, max_verse = 26 }, + { chapter = 8, max_verse = 35 }, + { chapter = 9, max_verse = 27 }, + { chapter = 10, max_verse = 43 }, + { chapter = 11, max_verse = 23 }, + { chapter = 12, max_verse = 24 }, + { chapter = 13, max_verse = 33 }, + { chapter = 14, max_verse = 15 }, + { chapter = 15, max_verse = 63 }, + { chapter = 16, max_verse = 10 }, + { chapter = 17, max_verse = 18 }, + { chapter = 18, max_verse = 28 }, + { chapter = 19, max_verse = 51 }, + { chapter = 20, max_verse = 9 }, + { chapter = 21, max_verse = 45 }, + { chapter = 22, max_verse = 34 }, + { chapter = 23, max_verse = 16 }, + { chapter = 24, max_verse = 33 }, + }, + jude = { { chapter = 1, max_verse = 25 } }, + judges = { + { chapter = 1, max_verse = 36 }, + { chapter = 2, max_verse = 23 }, + { chapter = 3, max_verse = 31 }, + { chapter = 4, max_verse = 24 }, + { chapter = 5, max_verse = 31 }, + { chapter = 6, max_verse = 40 }, + { chapter = 7, max_verse = 25 }, + { chapter = 8, max_verse = 35 }, + { chapter = 9, max_verse = 57 }, + { chapter = 10, max_verse = 18 }, + { chapter = 11, max_verse = 40 }, + { chapter = 12, max_verse = 15 }, + { chapter = 13, max_verse = 25 }, + { chapter = 14, max_verse = 20 }, + { chapter = 15, max_verse = 20 }, + { chapter = 16, max_verse = 31 }, + { chapter = 17, max_verse = 13 }, + { chapter = 18, max_verse = 31 }, + { chapter = 19, max_verse = 30 }, + { chapter = 20, max_verse = 48 }, + { chapter = 21, max_verse = 25 }, + }, + lamentations = { + { chapter = 1, max_verse = 22 }, + { chapter = 2, max_verse = 22 }, + { chapter = 3, max_verse = 66 }, + { chapter = 4, max_verse = 22 }, + { chapter = 5, max_verse = 22 }, + }, + leviticus = { + { chapter = 1, max_verse = 17 }, + { chapter = 2, max_verse = 16 }, + { chapter = 3, max_verse = 17 }, + { chapter = 4, max_verse = 35 }, + { chapter = 5, max_verse = 19 }, + { chapter = 6, max_verse = 30 }, + { chapter = 7, max_verse = 38 }, + { chapter = 8, max_verse = 36 }, + { chapter = 9, max_verse = 24 }, + { chapter = 10, max_verse = 20 }, + { chapter = 11, max_verse = 47 }, + { chapter = 12, max_verse = 8 }, + { chapter = 13, max_verse = 59 }, + { chapter = 14, max_verse = 57 }, + { chapter = 15, max_verse = 33 }, + { chapter = 16, max_verse = 34 }, + { chapter = 17, max_verse = 16 }, + { chapter = 18, max_verse = 30 }, + { chapter = 19, max_verse = 37 }, + { chapter = 20, max_verse = 27 }, + { chapter = 21, max_verse = 24 }, + { chapter = 22, max_verse = 33 }, + { chapter = 23, max_verse = 44 }, + { chapter = 24, max_verse = 23 }, + { chapter = 25, max_verse = 55 }, + { chapter = 26, max_verse = 46 }, + { chapter = 27, max_verse = 34 }, + }, + luke = { + { chapter = 1, max_verse = 80 }, + { chapter = 2, max_verse = 52 }, + { chapter = 3, max_verse = 38 }, + { chapter = 4, max_verse = 44 }, + { chapter = 5, max_verse = 39 }, + { chapter = 6, max_verse = 49 }, + { chapter = 7, max_verse = 50 }, + { chapter = 8, max_verse = 56 }, + { chapter = 9, max_verse = 62 }, + { chapter = 10, max_verse = 42 }, + { chapter = 11, max_verse = 54 }, + { chapter = 12, max_verse = 59 }, + { chapter = 13, max_verse = 35 }, + { chapter = 14, max_verse = 35 }, + { chapter = 15, max_verse = 32 }, + { chapter = 16, max_verse = 31 }, + { chapter = 17, max_verse = 37 }, + { chapter = 18, max_verse = 43 }, + { chapter = 19, max_verse = 48 }, + { chapter = 20, max_verse = 47 }, + { chapter = 21, max_verse = 38 }, + { chapter = 22, max_verse = 71 }, + { chapter = 23, max_verse = 56 }, + { chapter = 24, max_verse = 53 }, + }, + malachi = { + { chapter = 1, max_verse = 14 }, + { chapter = 2, max_verse = 17 }, + { chapter = 3, max_verse = 18 }, + { chapter = 4, max_verse = 6 }, + }, + mark = { + { chapter = 1, max_verse = 45 }, + { chapter = 2, max_verse = 28 }, + { chapter = 3, max_verse = 35 }, + { chapter = 4, max_verse = 41 }, + { chapter = 5, max_verse = 43 }, + { chapter = 6, max_verse = 56 }, + { chapter = 7, max_verse = 37 }, + { chapter = 8, max_verse = 38 }, + { chapter = 9, max_verse = 50 }, + { chapter = 10, max_verse = 52 }, + { chapter = 11, max_verse = 33 }, + { chapter = 12, max_verse = 44 }, + { chapter = 13, max_verse = 37 }, + { chapter = 14, max_verse = 72 }, + { chapter = 15, max_verse = 47 }, + { chapter = 16, max_verse = 20 }, + }, + matthew = { + { chapter = 1, max_verse = 25 }, + { chapter = 2, max_verse = 23 }, + { chapter = 3, max_verse = 17 }, + { chapter = 4, max_verse = 25 }, + { chapter = 5, max_verse = 48 }, + { chapter = 6, max_verse = 34 }, + { chapter = 7, max_verse = 29 }, + { chapter = 8, max_verse = 34 }, + { chapter = 9, max_verse = 38 }, + { chapter = 10, max_verse = 42 }, + { chapter = 11, max_verse = 30 }, + { chapter = 12, max_verse = 50 }, + { chapter = 13, max_verse = 58 }, + { chapter = 14, max_verse = 36 }, + { chapter = 15, max_verse = 39 }, + { chapter = 16, max_verse = 28 }, + { chapter = 17, max_verse = 27 }, + { chapter = 18, max_verse = 35 }, + { chapter = 19, max_verse = 30 }, + { chapter = 20, max_verse = 34 }, + { chapter = 21, max_verse = 46 }, + { chapter = 22, max_verse = 46 }, + { chapter = 23, max_verse = 39 }, + { chapter = 24, max_verse = 51 }, + { chapter = 25, max_verse = 46 }, + { chapter = 26, max_verse = 75 }, + { chapter = 27, max_verse = 66 }, + { chapter = 28, max_verse = 20 }, + }, + micah = { + { chapter = 1, max_verse = 16 }, + { chapter = 2, max_verse = 13 }, + { chapter = 3, max_verse = 12 }, + { chapter = 4, max_verse = 13 }, + { chapter = 5, max_verse = 15 }, + { chapter = 6, max_verse = 16 }, + { chapter = 7, max_verse = 20 }, + }, + nahum = { + { chapter = 1, max_verse = 15 }, + { chapter = 2, max_verse = 13 }, + { chapter = 3, max_verse = 19 }, + }, + nehemiah = { + { chapter = 1, max_verse = 11 }, + { chapter = 2, max_verse = 20 }, + { chapter = 3, max_verse = 32 }, + { chapter = 4, max_verse = 23 }, + { chapter = 5, max_verse = 19 }, + { chapter = 6, max_verse = 19 }, + { chapter = 7, max_verse = 73 }, + { chapter = 8, max_verse = 18 }, + { chapter = 9, max_verse = 38 }, + { chapter = 10, max_verse = 39 }, + { chapter = 11, max_verse = 36 }, + { chapter = 12, max_verse = 47 }, + { chapter = 13, max_verse = 31 }, + }, + numbers = { + { chapter = 1, max_verse = 54 }, + { chapter = 2, max_verse = 34 }, + { chapter = 3, max_verse = 51 }, + { chapter = 4, max_verse = 49 }, + { chapter = 5, max_verse = 31 }, + { chapter = 6, max_verse = 27 }, + { chapter = 7, max_verse = 89 }, + { chapter = 8, max_verse = 26 }, + { chapter = 9, max_verse = 23 }, + { chapter = 10, max_verse = 36 }, + { chapter = 11, max_verse = 35 }, + { chapter = 12, max_verse = 16 }, + { chapter = 13, max_verse = 33 }, + { chapter = 14, max_verse = 45 }, + { chapter = 15, max_verse = 41 }, + { chapter = 16, max_verse = 50 }, + { chapter = 17, max_verse = 13 }, + { chapter = 18, max_verse = 32 }, + { chapter = 19, max_verse = 22 }, + { chapter = 20, max_verse = 29 }, + { chapter = 21, max_verse = 35 }, + { chapter = 22, max_verse = 41 }, + { chapter = 23, max_verse = 30 }, + { chapter = 24, max_verse = 25 }, + { chapter = 25, max_verse = 18 }, + { chapter = 26, max_verse = 65 }, + { chapter = 27, max_verse = 23 }, + { chapter = 28, max_verse = 31 }, + { chapter = 29, max_verse = 40 }, + { chapter = 30, max_verse = 16 }, + { chapter = 31, max_verse = 54 }, + { chapter = 32, max_verse = 42 }, + { chapter = 33, max_verse = 56 }, + { chapter = 34, max_verse = 29 }, + { chapter = 35, max_verse = 34 }, + { chapter = 36, max_verse = 13 }, + }, + obadiah = { { chapter = 1, max_verse = 21 } }, + philemon = { { chapter = 1, max_verse = 25 } }, + philippians = { + { chapter = 1, max_verse = 30 }, + { chapter = 2, max_verse = 30 }, + { chapter = 3, max_verse = 21 }, + { chapter = 4, max_verse = 23 }, + }, + proverbs = { + { chapter = 1, max_verse = 33 }, + { chapter = 2, max_verse = 22 }, + { chapter = 3, max_verse = 35 }, + { chapter = 4, max_verse = 27 }, + { chapter = 5, max_verse = 23 }, + { chapter = 6, max_verse = 35 }, + { chapter = 7, max_verse = 27 }, + { chapter = 8, max_verse = 36 }, + { chapter = 9, max_verse = 18 }, + { chapter = 10, max_verse = 32 }, + { chapter = 11, max_verse = 31 }, + { chapter = 12, max_verse = 28 }, + { chapter = 13, max_verse = 25 }, + { chapter = 14, max_verse = 35 }, + { chapter = 15, max_verse = 33 }, + { chapter = 16, max_verse = 33 }, + { chapter = 17, max_verse = 28 }, + { chapter = 18, max_verse = 24 }, + { chapter = 19, max_verse = 29 }, + { chapter = 20, max_verse = 30 }, + { chapter = 21, max_verse = 31 }, + { chapter = 22, max_verse = 29 }, + { chapter = 23, max_verse = 35 }, + { chapter = 24, max_verse = 34 }, + { chapter = 25, max_verse = 28 }, + { chapter = 26, max_verse = 28 }, + { chapter = 27, max_verse = 27 }, + { chapter = 28, max_verse = 28 }, + { chapter = 29, max_verse = 27 }, + { chapter = 30, max_verse = 33 }, + { chapter = 31, max_verse = 31 }, + }, + psalms = { + { chapter = 1, max_verse = 6 }, + { chapter = 2, max_verse = 12 }, + { chapter = 3, max_verse = 8 }, + { chapter = 4, max_verse = 8 }, + { chapter = 5, max_verse = 12 }, + { chapter = 6, max_verse = 10 }, + { chapter = 7, max_verse = 17 }, + { chapter = 8, max_verse = 9 }, + { chapter = 9, max_verse = 20 }, + { chapter = 10, max_verse = 18 }, + { chapter = 11, max_verse = 7 }, + { chapter = 12, max_verse = 8 }, + { chapter = 13, max_verse = 6 }, + { chapter = 14, max_verse = 7 }, + { chapter = 15, max_verse = 5 }, + { chapter = 16, max_verse = 11 }, + { chapter = 17, max_verse = 15 }, + { chapter = 18, max_verse = 50 }, + { chapter = 19, max_verse = 14 }, + { chapter = 20, max_verse = 9 }, + { chapter = 21, max_verse = 13 }, + { chapter = 22, max_verse = 31 }, + { chapter = 23, max_verse = 6 }, + { chapter = 24, max_verse = 10 }, + { chapter = 25, max_verse = 22 }, + { chapter = 26, max_verse = 12 }, + { chapter = 27, max_verse = 14 }, + { chapter = 28, max_verse = 9 }, + { chapter = 29, max_verse = 11 }, + { chapter = 30, max_verse = 12 }, + { chapter = 31, max_verse = 24 }, + { chapter = 32, max_verse = 11 }, + { chapter = 33, max_verse = 22 }, + { chapter = 34, max_verse = 22 }, + { chapter = 35, max_verse = 28 }, + { chapter = 36, max_verse = 12 }, + { chapter = 37, max_verse = 40 }, + { chapter = 38, max_verse = 22 }, + { chapter = 39, max_verse = 13 }, + { chapter = 40, max_verse = 17 }, + { chapter = 41, max_verse = 13 }, + { chapter = 42, max_verse = 11 }, + { chapter = 43, max_verse = 5 }, + { chapter = 44, max_verse = 26 }, + { chapter = 45, max_verse = 17 }, + { chapter = 46, max_verse = 11 }, + { chapter = 47, max_verse = 9 }, + { chapter = 48, max_verse = 14 }, + { chapter = 49, max_verse = 20 }, + { chapter = 50, max_verse = 23 }, + { chapter = 51, max_verse = 19 }, + { chapter = 52, max_verse = 9 }, + { chapter = 53, max_verse = 6 }, + { chapter = 54, max_verse = 7 }, + { chapter = 55, max_verse = 23 }, + { chapter = 56, max_verse = 13 }, + { chapter = 57, max_verse = 11 }, + { chapter = 58, max_verse = 11 }, + { chapter = 59, max_verse = 17 }, + { chapter = 60, max_verse = 12 }, + { chapter = 61, max_verse = 8 }, + { chapter = 62, max_verse = 12 }, + { chapter = 63, max_verse = 11 }, + { chapter = 64, max_verse = 10 }, + { chapter = 65, max_verse = 13 }, + { chapter = 66, max_verse = 20 }, + { chapter = 67, max_verse = 7 }, + { chapter = 68, max_verse = 35 }, + { chapter = 69, max_verse = 36 }, + { chapter = 70, max_verse = 5 }, + { chapter = 71, max_verse = 24 }, + { chapter = 72, max_verse = 20 }, + { chapter = 73, max_verse = 28 }, + { chapter = 74, max_verse = 23 }, + { chapter = 75, max_verse = 10 }, + { chapter = 76, max_verse = 12 }, + { chapter = 77, max_verse = 20 }, + { chapter = 78, max_verse = 72 }, + { chapter = 79, max_verse = 13 }, + { chapter = 80, max_verse = 19 }, + { chapter = 81, max_verse = 16 }, + { chapter = 82, max_verse = 8 }, + { chapter = 83, max_verse = 18 }, + { chapter = 84, max_verse = 12 }, + { chapter = 85, max_verse = 13 }, + { chapter = 86, max_verse = 17 }, + { chapter = 87, max_verse = 7 }, + { chapter = 88, max_verse = 18 }, + { chapter = 89, max_verse = 52 }, + { chapter = 90, max_verse = 17 }, + { chapter = 91, max_verse = 16 }, + { chapter = 92, max_verse = 15 }, + { chapter = 93, max_verse = 5 }, + { chapter = 94, max_verse = 23 }, + { chapter = 95, max_verse = 11 }, + { chapter = 96, max_verse = 13 }, + { chapter = 97, max_verse = 12 }, + { chapter = 98, max_verse = 9 }, + { chapter = 99, max_verse = 9 }, + { chapter = 100, max_verse = 5 }, + { chapter = 101, max_verse = 8 }, + { chapter = 102, max_verse = 28 }, + { chapter = 103, max_verse = 22 }, + { chapter = 104, max_verse = 35 }, + { chapter = 105, max_verse = 45 }, + { chapter = 106, max_verse = 48 }, + { chapter = 107, max_verse = 43 }, + { chapter = 108, max_verse = 13 }, + { chapter = 109, max_verse = 31 }, + { chapter = 110, max_verse = 7 }, + { chapter = 111, max_verse = 10 }, + { chapter = 112, max_verse = 10 }, + { chapter = 113, max_verse = 9 }, + { chapter = 114, max_verse = 8 }, + { chapter = 115, max_verse = 18 }, + { chapter = 116, max_verse = 19 }, + { chapter = 117, max_verse = 2 }, + { chapter = 118, max_verse = 29 }, + { chapter = 119, max_verse = 176 }, + { chapter = 120, max_verse = 7 }, + { chapter = 121, max_verse = 8 }, + { chapter = 122, max_verse = 9 }, + { chapter = 123, max_verse = 4 }, + { chapter = 124, max_verse = 8 }, + { chapter = 125, max_verse = 5 }, + { chapter = 126, max_verse = 6 }, + { chapter = 127, max_verse = 5 }, + { chapter = 128, max_verse = 6 }, + { chapter = 129, max_verse = 8 }, + { chapter = 130, max_verse = 8 }, + { chapter = 131, max_verse = 3 }, + { chapter = 132, max_verse = 18 }, + { chapter = 133, max_verse = 3 }, + { chapter = 134, max_verse = 3 }, + { chapter = 135, max_verse = 21 }, + { chapter = 136, max_verse = 26 }, + { chapter = 137, max_verse = 9 }, + { chapter = 138, max_verse = 8 }, + { chapter = 139, max_verse = 24 }, + { chapter = 140, max_verse = 13 }, + { chapter = 141, max_verse = 10 }, + { chapter = 142, max_verse = 7 }, + { chapter = 143, max_verse = 12 }, + { chapter = 144, max_verse = 15 }, + { chapter = 145, max_verse = 21 }, + { chapter = 146, max_verse = 10 }, + { chapter = 147, max_verse = 20 }, + { chapter = 148, max_verse = 14 }, + { chapter = 149, max_verse = 9 }, + { chapter = 150, max_verse = 6 }, + }, + revelation = { + { chapter = 1, max_verse = 20 }, + { chapter = 2, max_verse = 29 }, + { chapter = 3, max_verse = 22 }, + { chapter = 4, max_verse = 11 }, + { chapter = 5, max_verse = 14 }, + { chapter = 6, max_verse = 17 }, + { chapter = 7, max_verse = 17 }, + { chapter = 8, max_verse = 13 }, + { chapter = 9, max_verse = 21 }, + { chapter = 10, max_verse = 11 }, + { chapter = 11, max_verse = 19 }, + { chapter = 12, max_verse = 17 }, + { chapter = 13, max_verse = 18 }, + { chapter = 14, max_verse = 20 }, + { chapter = 15, max_verse = 8 }, + { chapter = 16, max_verse = 21 }, + { chapter = 17, max_verse = 18 }, + { chapter = 18, max_verse = 24 }, + { chapter = 19, max_verse = 21 }, + { chapter = 20, max_verse = 15 }, + { chapter = 21, max_verse = 27 }, + { chapter = 22, max_verse = 21 }, + }, + romans = { + { chapter = 1, max_verse = 32 }, + { chapter = 2, max_verse = 29 }, + { chapter = 3, max_verse = 31 }, + { chapter = 4, max_verse = 25 }, + { chapter = 5, max_verse = 21 }, + { chapter = 6, max_verse = 23 }, + { chapter = 7, max_verse = 25 }, + { chapter = 8, max_verse = 39 }, + { chapter = 9, max_verse = 33 }, + { chapter = 10, max_verse = 21 }, + { chapter = 11, max_verse = 36 }, + { chapter = 12, max_verse = 21 }, + { chapter = 13, max_verse = 14 }, + { chapter = 14, max_verse = 23 }, + { chapter = 15, max_verse = 33 }, + { chapter = 16, max_verse = 27 }, + }, + ruth = { + { chapter = 1, max_verse = 22 }, + { chapter = 2, max_verse = 23 }, + { chapter = 3, max_verse = 18 }, + { chapter = 4, max_verse = 22 }, + }, + song = { + { chapter = 1, max_verse = 17 }, + { chapter = 2, max_verse = 17 }, + { chapter = 3, max_verse = 11 }, + { chapter = 4, max_verse = 16 }, + { chapter = 5, max_verse = 16 }, + { chapter = 6, max_verse = 13 }, + { chapter = 7, max_verse = 13 }, + { chapter = 8, max_verse = 14 }, + }, + titus = { + { chapter = 1, max_verse = 16 }, + { chapter = 2, max_verse = 15 }, + { chapter = 3, max_verse = 15 }, + }, + zechariah = { + { chapter = 1, max_verse = 21 }, + { chapter = 2, max_verse = 13 }, + { chapter = 3, max_verse = 10 }, + { chapter = 4, max_verse = 14 }, + { chapter = 5, max_verse = 11 }, + { chapter = 6, max_verse = 15 }, + { chapter = 7, max_verse = 14 }, + { chapter = 8, max_verse = 23 }, + { chapter = 9, max_verse = 17 }, + { chapter = 10, max_verse = 12 }, + { chapter = 11, max_verse = 17 }, + { chapter = 12, max_verse = 14 }, + { chapter = 13, max_verse = 9 }, + { chapter = 14, max_verse = 21 }, + }, + zephaniah = { + { chapter = 1, max_verse = 18 }, + { chapter = 2, max_verse = 15 }, + { chapter = 3, max_verse = 20 }, + }, +} + +---@type string[] +local books = { + "ezekiel", + "ezra", + "galatians", + "genesis", + "habakkuk", + "haggai", + "hebrews", + "hosea", + "isaiah", + "james", + "jeremiah", + "joel", + "john", + "jonah", + "joshua", + "jude", + "judges", + "lamentations", + "leviticus", + "job", + "malachi", + "matthew", + "micah", + "nahum", + "nehemiah", + "obadiah", + "philemon", + "philippians", + "proverbs", + "1chronicles", + "revelation", + "romans", + "ruth", + "song", + "titus", + "zechariah", + "numbers", + "zephaniah", + "psalms", + "mark", + "luke", + "1corinthians", + "1john", + "1kings", + "1peter", + "1samuel", + "1thessalonians", + "1timothy", + "2chronicles", + "2corinthians", + "2john", + "2kings", + "2peter", + "2samuel", + "2thessalonians", + "2timothy", + "3john", + "acts", + "amos", + "colossians", + "daniel", + "deuteronomy", + "ecclesiastes", + "ephesians", + "esther", + "exodus", +} + +function M.random_verse() + local book_name = books[math.random(1, #books)] + local book_chapter = math.random(1, #bible_data[book_name]) + local book_verse = math.random(1, bible_data[book_name][book_chapter].max_verse) + return book_name .. " " .. book_chapter .. ":" .. book_verse +end + +return M diff --git a/lua/bible-verse/formatter/bibleverse.lua b/lua/bible-verse/formatter/bibleverse.lua index 1fea88d..7fd8cef 100644 --- a/lua/bible-verse/formatter/bibleverse.lua +++ b/lua/bible-verse/formatter/bibleverse.lua @@ -4,46 +4,46 @@ local FormatterCommon = require("bible-verse.formatter.common") local M = {} --- Formats parsed diatheke output and format it in Markdown style. ----@param verses_table DiathekeVerse[] parsed diatheke output. +---@param verses_table Verse[] parsed diatheke output. ---@return string[] output individual lines of the output. function M.format(verses_table) - local res = {} - local sorted_bible_chapter = FormatterCommon.organise_by_sorted_bible_chapter(verses_table) - local sorted_bible_chapter_len = #sorted_bible_chapter - local use_separator = string.len(Config.options.formatter.bibleverse.separator) ~= 0 + local res = {} + local sorted_bible_chapter = FormatterCommon.organise_by_sorted_bible_chapter(verses_table) + local sorted_bible_chapter_len = #sorted_bible_chapter + local use_separator = string.len(Config.options.formatter.bibleverse.separator) ~= 0 - for idx, sorted_chap in ipairs(sorted_bible_chapter) do - table.insert(res, string.format("bc{%s}", sorted_chap.name)) - table.insert(res, "") + for idx, sorted_chap in ipairs(sorted_bible_chapter) do + table.insert(res, string.format("bc{%s}", sorted_chap.name)) + table.insert(res, "") - local chapter_res = {} - for v_idx, verse in ipairs(sorted_chap.verses) do - if v_idx > 1 and verse.verse_prefix_newline then - table.insert(res, table.concat(chapter_res)) - table.insert(res, "") - chapter_res = {} - end - table.insert( - chapter_res, - string.format("vn{%s}%s ", FormatterCommon.to_sup_num(verse.verse_number), verse.verse) - ) - end - table.insert(res, table.concat(chapter_res)) + local chapter_res = {} + for v_idx, verse in ipairs(sorted_chap.verses) do + if v_idx > 1 and verse.verse_prefix_newline then + table.insert(res, table.concat(chapter_res)) + table.insert(res, "") + chapter_res = {} + end + table.insert( + chapter_res, + string.format("vn{%s}%s ", FormatterCommon.to_sup_num(verse.verse_number), verse.verse) + ) + end + table.insert(res, table.concat(chapter_res)) - if idx < sorted_bible_chapter_len then - table.insert(res, "") - if use_separator then - table.insert(res, string.format("sp{%s}", Config.options.formatter.bibleverse.separator)) - end - table.insert(res, "") - end - end - if not Config.options.formatter.bibleverse.omit_translation_footnote then - table.insert(res, "") - table.insert(res, string.format("t{%s}", Config.options.diatheke.translation)) - end + if idx < sorted_bible_chapter_len then + table.insert(res, "") + if use_separator then + table.insert(res, string.format("sp{%s}", Config.options.formatter.bibleverse.separator)) + end + table.insert(res, "") + end + end + if not Config.options.formatter.bibleverse.omit_translation_footnote then + table.insert(res, "") + table.insert(res, string.format("t{%s}", Config.options.diatheke.translation)) + end - return res + return res end return M diff --git a/lua/bible-verse/formatter/common.lua b/lua/bible-verse/formatter/common.lua index 6978cff..155a532 100644 --- a/lua/bible-verse/formatter/common.lua +++ b/lua/bible-verse/formatter/common.lua @@ -1,48 +1,48 @@ local M = {} local sup_nums = { - ["0"] = "⁰", - ["1"] = "¹", - ["2"] = "²", - ["3"] = "³", - ["4"] = "⁴", - ["5"] = "⁵", - ["6"] = "⁶", - ["7"] = "⁷", - ["8"] = "⁸", - ["9"] = "⁹", + ["0"] = "⁰", + ["1"] = "¹", + ["2"] = "²", + ["3"] = "³", + ["4"] = "⁴", + ["5"] = "⁵", + ["6"] = "⁶", + ["7"] = "⁷", + ["8"] = "⁸", + ["9"] = "⁹", } --- Convert to super script ---@param num string integer to convert ---@return string supscript_num num in super script function M.to_sup_num(num) - local str_tbl = {} - for c in num:gmatch(".") do - table.insert(str_tbl, sup_nums[c]) - end - return table.concat(str_tbl) + local str_tbl = {} + for c in num:gmatch(".") do + table.insert(str_tbl, sup_nums[c]) + end + return table.concat(str_tbl) end --- Format verses_table by book:chapter. ----@param verses_table DiathekeVerse[] parsed diatheke output. ----@return { name: string, verses: DiathekeVerse[]}[] sorted_verse_table sorted output +---@param verses_table Verse[] parsed diatheke output. +---@return { name: string, verses: Verse[]}[] sorted_verse_table sorted output function M.organise_by_sorted_bible_chapter(verses_table) - local sorted_bible_chapter = {} - for _, verse in ipairs(verses_table) do - local book_chapter_name = string.format("%s %s", verse.book, verse.chapter) - if - sorted_bible_chapter[#sorted_bible_chapter] == nil - or sorted_bible_chapter[#sorted_bible_chapter].name ~= book_chapter_name - then - table.insert(sorted_bible_chapter, { - name = book_chapter_name, - verses = {}, - }) - end - table.insert(sorted_bible_chapter[#sorted_bible_chapter].verses, verse) - end - return sorted_bible_chapter + local sorted_bible_chapter = {} + for _, verse in ipairs(verses_table) do + local book_chapter_name = string.format("%s %s", verse.book, verse.chapter) + if + sorted_bible_chapter[#sorted_bible_chapter] == nil + or sorted_bible_chapter[#sorted_bible_chapter].name ~= book_chapter_name + then + table.insert(sorted_bible_chapter, { + name = book_chapter_name, + verses = {}, + }) + end + table.insert(sorted_bible_chapter[#sorted_bible_chapter].verses, verse) + end + return sorted_bible_chapter end return M diff --git a/lua/bible-verse/formatter/init.lua b/lua/bible-verse/formatter/init.lua index 3e66fdb..8ed34db 100644 --- a/lua/bible-verse/formatter/init.lua +++ b/lua/bible-verse/formatter/init.lua @@ -1,7 +1,7 @@ local Config = require("bible-verse.config") ---@alias FormatterType "plain"|"markdown"|"bibleverse" ----@alias FormatFunc fun(verses_table: DiathekeVerse[]): string[] +---@alias FormatFunc fun(verses_table: Verse[]): string[] local M = {} @@ -9,34 +9,34 @@ local M = {} M.formatters = {} ---Format based on given formatter type ----@param verses_table DiathekeVerse[] pased diatheke output +---@param verses_table Verse[] pased diatheke output ---@param formatter_type FormatterType type of formatter ---@return string[] output individual lines of the output function M.format(verses_table, formatter_type) - if M.formatters[formatter_type] == nil then - error("unsupported formatter|formatter_type=" .. formatter_type) - end - return M.formatters[formatter_type](verses_table) + if M.formatters[formatter_type] == nil then + error("unsupported formatter|formatter_type=" .. formatter_type) + end + return M.formatters[formatter_type](verses_table) end function M.setup() - M.formatters = { - markdown = function(verses_table) - return require("bible-verse.formatter.markdown").format(verses_table) - end, - bibleverse = function(verses_table) - return require("bible-verse.formatter.bibleverse").format(verses_table) - end, - plain = function(verses_table) - return require("bible-verse.formatter.plain").format(verses_table) - end, - } + M.formatters = { + markdown = function(verses_table) + return require("bible-verse.formatter.markdown").format(verses_table) + end, + bibleverse = function(verses_table) + return require("bible-verse.formatter.bibleverse").format(verses_table) + end, + plain = function(verses_table) + return require("bible-verse.formatter.plain").format(verses_table) + end, + } - -- Check that config is sane - assert( - M.formatters[Config.options.insert_format] ~= nil, - "unsupported formatter|formatter_type=" .. Config.options.insert_format - ) + -- Check that config is sane + assert( + M.formatters[Config.options.insert_format] ~= nil, + "unsupported formatter|formatter_type=" .. Config.options.insert_format + ) end return M diff --git a/lua/bible-verse/formatter/markdown.lua b/lua/bible-verse/formatter/markdown.lua index 75271ce..df342d7 100644 --- a/lua/bible-verse/formatter/markdown.lua +++ b/lua/bible-verse/formatter/markdown.lua @@ -4,47 +4,47 @@ local FormatterCommon = require("bible-verse.formatter.common") local M = {} --- Formats parsed diatheke output and format it in Markdown style. ----@param verses_table DiathekeVerse[] parsed diatheke output. +---@param verses_table Verse[] parsed diatheke output. ---@return string[] output individual lines of the output. function M.format(verses_table) - local res = {} - local sorted_bible_chapter = FormatterCommon.organise_by_sorted_bible_chapter(verses_table) - local sorted_bible_chapter_len = #sorted_bible_chapter - local use_separator = string.len(Config.options.formatter.markdown.separator) ~= 0 - local quote_block_char = "" + local res = {} + local sorted_bible_chapter = FormatterCommon.organise_by_sorted_bible_chapter(verses_table) + local sorted_bible_chapter_len = #sorted_bible_chapter + local use_separator = string.len(Config.options.formatter.markdown.separator) ~= 0 + local quote_block_char = "" - if Config.options.formatter.markdown.quote_block then - quote_block_char = "> " - end - for idx, sorted_chap in ipairs(sorted_bible_chapter) do - table.insert(res, string.format("%s**%s**", quote_block_char, sorted_chap.name)) - table.insert(res, string.format("%s", quote_block_char)) + if Config.options.formatter.markdown.quote_block then + quote_block_char = "> " + end + for idx, sorted_chap in ipairs(sorted_bible_chapter) do + table.insert(res, string.format("%s**%s**", quote_block_char, sorted_chap.name)) + table.insert(res, string.format("%s", quote_block_char)) - local chapter_res = {} - for v_idx, verse in ipairs(sorted_chap.verses) do - if v_idx > 1 and verse.verse_prefix_newline then - table.insert(res, string.format("%s%s", quote_block_char, table.concat(chapter_res))) - table.insert(res, string.format("%s", quote_block_char)) - chapter_res = {} - end - table.insert(chapter_res, string.format("%s%s ", verse.verse_number, verse.verse)) - end - table.insert(res, string.format("%s%s", quote_block_char, table.concat(chapter_res))) + local chapter_res = {} + for v_idx, verse in ipairs(sorted_chap.verses) do + if v_idx > 1 and verse.verse_prefix_newline then + table.insert(res, string.format("%s%s", quote_block_char, table.concat(chapter_res))) + table.insert(res, string.format("%s", quote_block_char)) + chapter_res = {} + end + table.insert(chapter_res, string.format("%s%s ", verse.verse_number, verse.verse)) + end + table.insert(res, string.format("%s%s", quote_block_char, table.concat(chapter_res))) - if idx < sorted_bible_chapter_len then - table.insert(res, string.format("%s", quote_block_char)) - if use_separator then - table.insert(res, string.format("%s%s", quote_block_char, Config.options.formatter.markdown.separator)) - end - table.insert(res, string.format("%s", quote_block_char)) - end - end - if not Config.options.formatter.markdown.omit_translation_footnote then - table.insert(res, string.format("%s", quote_block_char)) - table.insert(res, string.format("%s*%s*", quote_block_char, Config.options.diatheke.translation)) - end + if idx < sorted_bible_chapter_len then + table.insert(res, string.format("%s", quote_block_char)) + if use_separator then + table.insert(res, string.format("%s%s", quote_block_char, Config.options.formatter.markdown.separator)) + end + table.insert(res, string.format("%s", quote_block_char)) + end + end + if not Config.options.formatter.markdown.omit_translation_footnote then + table.insert(res, string.format("%s", quote_block_char)) + table.insert(res, string.format("%s*%s*", quote_block_char, Config.options.diatheke.translation)) + end - return res + return res end return M diff --git a/lua/bible-verse/formatter/plain.lua b/lua/bible-verse/formatter/plain.lua index 8e486b3..37046e3 100644 --- a/lua/bible-verse/formatter/plain.lua +++ b/lua/bible-verse/formatter/plain.lua @@ -3,30 +3,30 @@ local Config = require("bible-verse.config") local M = {} --- Formats parsed diatheke output and format it in plain text format. ----@param verses_table DiathekeVerse[] parsed diatheke output. +---@param verses_table Verse[] parsed diatheke output. ---@return string[] output table of individual lines of the output. function M.format(verses_table) - local res = {} + local res = {} - for _, verse in ipairs(verses_table) do - table.insert( - res, - string.format( - "%s %s:%s%s%s", - verse.book, - verse.chapter, - verse.verse_number, - Config.options.formatter.plain.header_delimiter, - verse.verse - ) - ) - end - if not Config.options.formatter.plain.omit_translation_footnote then - table.insert(res, "") - table.insert(res, Config.options.diatheke.translation) - end + for _, verse in ipairs(verses_table) do + table.insert( + res, + string.format( + "%s %s:%s%s%s", + verse.book, + verse.chapter, + verse.verse_number, + Config.options.formatter.plain.header_delimiter, + verse.verse + ) + ) + end + if not Config.options.formatter.plain.omit_translation_footnote then + table.insert(res, "") + table.insert(res, Config.options.diatheke.translation) + end - return res + return res end return M diff --git a/lua/bible-verse/health.lua b/lua/bible-verse/health.lua index a88d76b..f89bb7a 100644 --- a/lua/bible-verse/health.lua +++ b/lua/bible-verse/health.lua @@ -9,48 +9,48 @@ local M = {} ---@param success_msg string success message ---@param err_msg string error message function M.report(checkhealth, result, severity, success_msg, err_msg) - local res_severity = result and "ok" or severity - local res_message = result and success_msg or err_msg - if checkhealth then - vim.health[res_severity](res_message) - end - return result + local res_severity = result and "ok" or severity + local res_message = result and success_msg or err_msg + if checkhealth then + vim.health[res_severity](res_message) + end + return result end ---@param opts? { checkhealth?: boolean } function M.check(opts) - opts = opts or {} - opts.checkhealth = opts.checkhealth == nil and true or opts.checkhealth - - local neovim_version_ok = M.report( - opts.checkhealth, - vim.fn.has("nvim-0.9.1") == 1, - "error", - "Neovim >= 0.9.1", - "BibleVerse needs Neovim >= 0.9.1" - ) - - local diatheke_ok = M.report( - opts.checkhealth, - Utils.command_exists("diatheke"), - "error", - "diatheke is installed", - "diatheke is not installed" - ) - - local nui_ok = M.report( - opts.checkhealth, - Utils.module_exists("nui.popup") - and Utils.module_exists("nui.input") - and Utils.module_exists("nui.utils.autocmd"), - "error", - "nui.nvim is installed", - "nui.nvim is not installed" - ) - - local overall_healthy = neovim_version_ok and diatheke_ok and nui_ok - - return overall_healthy + opts = opts or {} + opts.checkhealth = opts.checkhealth == nil and true or opts.checkhealth + + local neovim_version_ok = M.report( + opts.checkhealth, + vim.fn.has("nvim-0.9.1") == 1, + "error", + "Neovim >= 0.9.1", + "BibleVerse needs Neovim >= 0.9.1" + ) + + local diatheke_ok = M.report( + opts.checkhealth, + Utils.command_exists("diatheke"), + "error", + "diatheke is installed", + "diatheke is not installed" + ) + + local nui_ok = M.report( + opts.checkhealth, + Utils.module_exists("nui.popup") + and Utils.module_exists("nui.input") + and Utils.module_exists("nui.utils.autocmd"), + "error", + "nui.nvim is installed", + "nui.nvim is not installed" + ) + + local overall_healthy = neovim_version_ok and diatheke_ok and nui_ok + + return overall_healthy end return M diff --git a/lua/bible-verse/init.lua b/lua/bible-verse/init.lua index 0b27808..ffb34db 100644 --- a/lua/bible-verse/init.lua +++ b/lua/bible-verse/init.lua @@ -2,30 +2,35 @@ local M = {} ---@param opts? table M.setup = function(opts) - opts = opts or {} + opts = opts or {} - -- Run healthcheck first - if not require("bible-verse.health").check({ checkhealth = false }) then - vim.notify_once( - "bible-verse.nvim: checkhealth failed. Please run :checkhealth bible-verse.", - vim.log.levels.ERROR - ) - return - end + -- Run healthcheck first + if not require("bible-verse.health").check({ checkhealth = false }) then + vim.notify_once( + "bible-verse.nvim: checkhealth failed. Please run :checkhealth bible-verse.", + vim.log.levels.ERROR + ) + return + end - local function load() - require("bible-verse.config").setup(opts) - require("bible-verse.commands").setup() - require("bible-verse.formatter").setup() - require("bible-verse.core").setup() - end + local function load() + require("bible-verse.config").setup(opts) + require("bible-verse.commands").setup() + require("bible-verse.formatter").setup() + require("bible-verse.core").setup() + end - load() + load() end +-- Exposed APIs + ---@param command? BibleVerseCmd M.cmd = function(command) - require("bible-verse.commands").cmd(command) + require("bible-verse.commands").cmd(command) end +M.query = require("bible-verse.core").query +M.query_and_show = require("bible-verse.core").query_and_show +M.query_and_insert = require("bible-verse.core").query_and_insert return M diff --git a/lua/bible-verse/utils/init.lua b/lua/bible-verse/utils/init.lua index d6e2848..76f08aa 100644 --- a/lua/bible-verse/utils/init.lua +++ b/lua/bible-verse/utils/init.lua @@ -3,13 +3,13 @@ local M = {} ---@param cmd string ---@return boolean exists function M.command_exists(cmd) - return vim.fn.executable(cmd) ~= 0 + return vim.fn.executable(cmd) ~= 0 end ---@param mod string ---@return boolean exists function M.module_exists(mod) - return pcall(_G.require, mod) == true + return pcall(_G.require, mod) == true end ---@param x number @@ -17,7 +17,7 @@ end ---@param max number ---@return number clamped function M.clamp(x, min, max) - return math.min(max, math.max(min, x)) + return math.min(max, math.max(min, x)) end --- Get current window width and height. @@ -26,103 +26,103 @@ end ---@param disable_floating_fallback_to_editor? boolean disable fallback ---@return { width: integer, height: integer } size in number of cells function M.get_win_size(win, disable_floating_fallback_to_editor) - win = win or vim.api.nvim_get_current_win() - disable_floating_fallback_to_editor = disable_floating_fallback_to_editor == nil or true - - if vim.api.nvim_win_get_config(win).relative ~= "" and disable_floating_fallback_to_editor then - return M.get_editor_size() - else - return { - width = vim.api.nvim_win_get_width(win), - height = vim.api.nvim_win_get_height(win), - } - end + win = win or vim.api.nvim_get_current_win() + disable_floating_fallback_to_editor = disable_floating_fallback_to_editor == nil or true + + if vim.api.nvim_win_get_config(win).relative ~= "" and disable_floating_fallback_to_editor then + return M.get_editor_size() + else + return { + width = vim.api.nvim_win_get_width(win), + height = vim.api.nvim_win_get_height(win), + } + end end ---@return { width: integer, height: integer } size in number of cells function M.get_editor_size() - return { - width = vim.o.columns, - height = vim.o.lines, - } + return { + width = vim.o.columns, + height = vim.o.lines, + } end ---@param type "'cursor'"|"'editor'"|"'win'" ---@return { width: integer, height: integer } size in number of cells function M.get_relative_size(type) - if type == "editor" then - return M.get_editor_size() - elseif type == "win" or type == "cursor" then - return M.get_win_size() - else - -- Fallback - return M.get_editor_size() - end + if type == "editor" then + return M.get_editor_size() + elseif type == "win" or type == "cursor" then + return M.get_win_size() + else + -- Fallback + return M.get_editor_size() + end end ---@param buf integer buffer handler ---@param exclude? string[] type of buffers to exclude ---@return boolean function M.is_valid_buf(buf, exclude) - exclude = exclude or {} - - if not vim.api.nvim_buf_is_valid(buf) then - vim.notify("Invalid buffer: " .. tostring(buf)) - return false - end - - -- Skip special buffers - local buftype = vim.api.nvim_get_option_value("buftype", { buf = buf }) - if buftype == "" and buftype == "quickfix" then - vim.notify("Invalid buffer, buftype_invalid: " .. tostring(buf) .. "|buftype=" .. buftype) - return false - end - - local filetype = vim.api.nvim_get_option_value("filetype", { buf = buf }) - if vim.tbl_contains(exclude, filetype) then - vim.notify("Invalid buffer, filetype_invalid: " .. tostring(buf) .. "|filetype=" .. filetype) - return false - end - - return true + exclude = exclude or {} + + if not vim.api.nvim_buf_is_valid(buf) then + vim.notify("Invalid buffer: " .. tostring(buf)) + return false + end + + -- Skip special buffers + local buftype = vim.api.nvim_get_option_value("buftype", { buf = buf }) + if buftype == "" and buftype == "quickfix" then + vim.notify("Invalid buffer, buftype_invalid: " .. tostring(buf) .. "|buftype=" .. buftype) + return false + end + + local filetype = vim.api.nvim_get_option_value("filetype", { buf = buf }) + if vim.tbl_contains(exclude, filetype) then + vim.notify("Invalid buffer, filetype_invalid: " .. tostring(buf) .. "|filetype=" .. filetype) + return false + end + + return true end ---@param win number window handler ---@return boolean function M.is_valid_win(win) - return vim.api.nvim_win_is_valid(win) + return vim.api.nvim_win_is_valid(win) end ---@param s string trimmed leading and trailing whitespace function M.trim(s) - return s:match("^%s*(.*%S)") or "" + return s:match("^%s*(.*%S)") or "" end ---@param str_arr string[] output to wrap ---@param limit number character length ---@return string[] output that is wrapped function M.wrap(str_arr, limit) - if limit <= 0 then - return str_arr - end - - local lines, whitespace_re = {}, "()%S+()" - for _, str in ipairs(str_arr) do - if str:len() <= limit then - table.insert(lines, str) - else - local start = 1 - str:gsub(whitespace_re, function(word_start_idx, next_word_start_idx) - if next_word_start_idx - start > limit and (word_start_idx - 1 - start > 0) then - table.insert(lines, M.trim(str:sub(start, word_start_idx - 1))) - start = word_start_idx - end - end) - table.insert(lines, M.trim(str:sub(start))) - end - end - - return lines + if limit <= 0 then + return str_arr + end + + local lines, whitespace_re = {}, "()%S+()" + for _, str in ipairs(str_arr) do + if str:len() <= limit then + table.insert(lines, str) + else + local start = 1 + str:gsub(whitespace_re, function(word_start_idx, next_word_start_idx) + if next_word_start_idx - start > limit and (word_start_idx - 1 - start > 0) then + table.insert(lines, M.trim(str:sub(start, word_start_idx - 1))) + start = word_start_idx + end + end) + table.insert(lines, M.trim(str:sub(start))) + end + end + + return lines end return M