Render KJV footnotes and lemma margin line
This commit is contained in:
Generated
+1
-1
@@ -77,7 +77,7 @@ checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"
|
||||
|
||||
[[package]]
|
||||
name = "app"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rusqlite",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "app"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
description = "A Tauri App"
|
||||
authors = ["you"]
|
||||
license = ""
|
||||
|
||||
+118
-1
@@ -43,6 +43,7 @@ struct Verse {
|
||||
verse: i64,
|
||||
text: String,
|
||||
strongs: Vec<StrongLink>,
|
||||
footnotes: Vec<Footnote>,
|
||||
tags: Vec<Tag>,
|
||||
}
|
||||
|
||||
@@ -64,6 +65,17 @@ struct Tag {
|
||||
color: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Footnote {
|
||||
id: i64,
|
||||
verse_id: i64,
|
||||
note_index: i64,
|
||||
caller: String,
|
||||
reference: String,
|
||||
text: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ImportedVerse {
|
||||
id: String,
|
||||
@@ -81,6 +93,15 @@ struct ImportedStrongLink {
|
||||
strong: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ImportedFootnote {
|
||||
verse_id: String,
|
||||
note_index: i64,
|
||||
caller: String,
|
||||
reference: String,
|
||||
text: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct LibreBibleIndexCatalog {
|
||||
resources: Vec<LibreBibleResourceSummary>,
|
||||
@@ -106,6 +127,7 @@ struct LibreBibleResourceCatalog {
|
||||
struct LibreBiblePackageFiles {
|
||||
verses_jsonl: Option<LibreBiblePackageFile>,
|
||||
strongs_jsonl: Option<LibreBiblePackageFile>,
|
||||
footnotes_jsonl: Option<LibreBiblePackageFile>,
|
||||
entries_jsonl: Option<LibreBiblePackageFile>,
|
||||
}
|
||||
|
||||
@@ -120,6 +142,7 @@ struct LibreBiblePackageSource {
|
||||
package_dir: PathBuf,
|
||||
verses_path: PathBuf,
|
||||
strongs_path: Option<PathBuf>,
|
||||
footnotes_path: Option<PathBuf>,
|
||||
lexicon_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
@@ -243,6 +266,16 @@ fn migrate(conn: &Connection) -> Result<(), String> {
|
||||
FOREIGN KEY (strong) REFERENCES lexicon(strong)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS verse_footnotes (
|
||||
id INTEGER PRIMARY KEY,
|
||||
verse_id INTEGER NOT NULL,
|
||||
note_index INTEGER NOT NULL,
|
||||
caller TEXT NOT NULL,
|
||||
reference TEXT NOT NULL,
|
||||
text TEXT NOT NULL,
|
||||
FOREIGN KEY (verse_id) REFERENCES verses(id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tags (
|
||||
id INTEGER PRIMARY KEY,
|
||||
label TEXT NOT NULL COLLATE NOCASE UNIQUE,
|
||||
@@ -337,6 +370,7 @@ fn reset_resource_cache(conn: &Connection) -> Result<(), String> {
|
||||
"
|
||||
DELETE FROM verse_tags;
|
||||
DELETE FROM verse_strongs;
|
||||
DELETE FROM verse_footnotes;
|
||||
DELETE FROM lexicon;
|
||||
DELETE FROM verses;
|
||||
DELETE FROM library_sources;
|
||||
@@ -497,6 +531,9 @@ fn load_package_source_from_package_dir(
|
||||
strongs_jsonl: Some(LibreBiblePackageFile {
|
||||
path: "strongs-links.jsonl".to_string(),
|
||||
}),
|
||||
footnotes_jsonl: Some(LibreBiblePackageFile {
|
||||
path: "footnotes.jsonl".to_string(),
|
||||
}),
|
||||
entries_jsonl: None,
|
||||
};
|
||||
|
||||
@@ -534,6 +571,11 @@ fn package_source_from_files(
|
||||
.as_ref()
|
||||
.map(|file| package_dir.join(&file.path))
|
||||
.filter(|path| path.exists());
|
||||
let footnotes_path = files
|
||||
.footnotes_jsonl
|
||||
.as_ref()
|
||||
.map(|file| package_dir.join(&file.path))
|
||||
.filter(|path| path.exists());
|
||||
let lexicon_path = files
|
||||
.entries_jsonl
|
||||
.as_ref()
|
||||
@@ -546,6 +588,7 @@ fn package_source_from_files(
|
||||
package_dir,
|
||||
verses_path,
|
||||
strongs_path,
|
||||
footnotes_path,
|
||||
lexicon_path,
|
||||
})
|
||||
}
|
||||
@@ -694,6 +737,39 @@ fn import_package(
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(footnotes_path) = package_source.footnotes_path {
|
||||
let file = File::open(&footnotes_path)
|
||||
.map_err(|err| format!("Unable to open {}: {err}", footnotes_path.display()))?;
|
||||
let reader = BufReader::new(file);
|
||||
|
||||
for (index, line) in reader.lines().enumerate() {
|
||||
let line = line.map_err(|err| err.to_string())?;
|
||||
if line.trim().is_empty() {
|
||||
continue;
|
||||
}
|
||||
let imported: ImportedFootnote =
|
||||
serde_json::from_str(&line).map_err(|err| err.to_string())?;
|
||||
let Some(verse_id) = verse_ids.get(&imported.verse_id) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
tx.execute(
|
||||
"INSERT OR REPLACE INTO verse_footnotes
|
||||
(id, verse_id, note_index, caller, reference, text)
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
|
||||
params![
|
||||
(index + 1) as i64,
|
||||
verse_id,
|
||||
imported.note_index,
|
||||
imported.caller,
|
||||
imported.reference,
|
||||
imported.text
|
||||
],
|
||||
)
|
||||
.map_err(|err| err.to_string())?;
|
||||
}
|
||||
}
|
||||
|
||||
tx.commit().map_err(|err| err.to_string())
|
||||
}
|
||||
|
||||
@@ -805,12 +881,14 @@ fn row_to_verse_shell(row: &rusqlite::Row<'_>) -> rusqlite::Result<Verse> {
|
||||
verse: row.get(3)?,
|
||||
text: row.get(4)?,
|
||||
strongs: Vec::new(),
|
||||
footnotes: Vec::new(),
|
||||
tags: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
fn hydrate_verse(conn: &Connection, mut verse: Verse) -> Result<Verse, String> {
|
||||
verse.strongs = load_strongs(conn, verse.id)?;
|
||||
verse.footnotes = load_footnotes(conn, verse.id)?;
|
||||
verse.tags = load_tags(conn, verse.id)?;
|
||||
Ok(verse)
|
||||
}
|
||||
@@ -849,6 +927,38 @@ fn load_strongs(conn: &Connection, verse_id: i64) -> Result<Vec<StrongLink>, Str
|
||||
Ok(entries)
|
||||
}
|
||||
|
||||
fn load_footnotes(conn: &Connection, verse_id: i64) -> Result<Vec<Footnote>, String> {
|
||||
let mut stmt = conn
|
||||
.prepare(
|
||||
"
|
||||
SELECT id, verse_id, note_index, caller, reference, text
|
||||
FROM verse_footnotes
|
||||
WHERE verse_id = ?1
|
||||
ORDER BY note_index, id
|
||||
",
|
||||
)
|
||||
.map_err(|err| err.to_string())?;
|
||||
|
||||
let rows = stmt
|
||||
.query_map(params![verse_id], |row| {
|
||||
Ok(Footnote {
|
||||
id: row.get(0)?,
|
||||
verse_id: row.get(1)?,
|
||||
note_index: row.get(2)?,
|
||||
caller: row.get(3)?,
|
||||
reference: row.get(4)?,
|
||||
text: row.get(5)?,
|
||||
})
|
||||
})
|
||||
.map_err(|err| err.to_string())?;
|
||||
|
||||
let mut entries = Vec::new();
|
||||
for row in rows {
|
||||
entries.push(row.map_err(|err| err.to_string())?);
|
||||
}
|
||||
Ok(entries)
|
||||
}
|
||||
|
||||
fn add_column_if_missing(
|
||||
conn: &Connection,
|
||||
table: &str,
|
||||
@@ -887,8 +997,11 @@ fn needs_resource_refresh(conn: &Connection) -> Result<bool, String> {
|
||||
|row| row.get(0),
|
||||
)
|
||||
.map_err(|err| err.to_string())?;
|
||||
let footnote_count: i64 = conn
|
||||
.query_row("SELECT COUNT(*) FROM verse_footnotes", [], |row| row.get(0))
|
||||
.map_err(|err| err.to_string())?;
|
||||
|
||||
Ok(lexicon_count < 10_000 || real_definition_count < 10_000)
|
||||
Ok(lexicon_count < 10_000 || real_definition_count < 10_000 || footnote_count < 6_000)
|
||||
}
|
||||
|
||||
fn find_catalog_lexicon_path(
|
||||
@@ -1031,6 +1144,9 @@ mod tests {
|
||||
let strongs_count: i64 = conn
|
||||
.query_row("SELECT COUNT(*) FROM verse_strongs", [], |row| row.get(0))
|
||||
.map_err(|err| err.to_string())?;
|
||||
let footnotes_count: i64 = conn
|
||||
.query_row("SELECT COUNT(*) FROM verse_footnotes", [], |row| row.get(0))
|
||||
.map_err(|err| err.to_string())?;
|
||||
let source_count: i64 = conn
|
||||
.query_row("SELECT COUNT(*) FROM library_sources", [], |row| row.get(0))
|
||||
.map_err(|err| err.to_string())?;
|
||||
@@ -1047,6 +1163,7 @@ mod tests {
|
||||
|
||||
assert_eq!(verse_count, 31_102);
|
||||
assert_eq!(strongs_count, 348_884);
|
||||
assert_eq!(footnotes_count, 6_959);
|
||||
assert_eq!(lexicon_count, 14_197);
|
||||
assert!(g25_definition.contains("to love"));
|
||||
assert_eq!(source_count, 1);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||
"productName": "Libre Study",
|
||||
"version": "0.1.6",
|
||||
"version": "0.1.7",
|
||||
"identifier": "org.librestudy.desktop",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
|
||||
Reference in New Issue
Block a user