aboutsummaryrefslogtreecommitdiff
path: root/sword.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sword.cc')
-rw-r--r--sword.cc145
1 files changed, 145 insertions, 0 deletions
diff --git a/sword.cc b/sword.cc
new file mode 100644
index 0000000..0bf20e2
--- /dev/null
+++ b/sword.cc
@@ -0,0 +1,145 @@
+#include "sword.h"
+#include <libbible.h>
+#include <sstream>
+#include <wctype.h>
+
+using namespace std;
+
+bool isNoMods;
+
+Sword::Sword() {
+ auto mods = libbible::getModules();
+ isNoMods = mods.empty();
+ defaultMod = libbible::settingsRead("module");
+ if(mods.find(defaultMod) == mods.end()) {
+ defaultMod = string();
+ if(! mods.empty()) {
+ defaultMod = mods.begin()->first;
+ }
+ }
+}
+
+Sword::~Sword() {}
+
+vector<string> Sword::getModules() {
+ vector<string> mods;
+ auto modsInstalled = libbible::getModules();
+ for(auto pair : modsInstalled) {
+ mods.push_back(pair.first);
+ }
+ return mods;
+}
+
+void Sword::setModule(string version) {
+ defaultMod = version;
+}
+
+void Sword::fillBuffer(string ref, Glib::RefPtr<Gtk::TextBuffer> buf) {
+ buf->set_text(""); // Clear contents
+
+ if(isNoMods) {
+ auto iter = buf->get_iter_at_offset(0);
+ iter = buf->insert_markup(iter, "<big><b>No modules installed.</b></big>\n");
+ iter = buf->insert_markup(iter, "Please download some modules at:\n");
+ iter = buf->insert_markup(iter, "\thttp://crosswire.org/sword/modules/ModDisp.jsp?modType=Bibles\n");
+ iter = buf->insert_markup(iter, "Then install them using the menu in the upper right corner, or use the built-in installer to download and install modules.");
+ return;
+ }
+
+ auto texts = libbible::getText(libbible::passage{.modName = defaultMod, .reference = ref});
+
+ auto iter = buf->get_iter_at_offset(0);
+
+ auto verseSize = buf->create_tag();
+ verseSize->property_size() = libbible::settingsReadInt("fontsize");
+ if(verseSize->property_size() == 0) {
+ verseSize->property_size() = 12000;
+ }
+
+ auto verseScale = buf->create_tag();
+ verseScale->property_scale() = 0.8;
+ auto verseOffset = buf->create_tag();
+ verseOffset->property_rise() = 3000;
+ auto indent = buf->create_tag();
+ indent->property_left_margin() = 40;
+ auto redletter = buf->create_tag();
+ redletter->property_foreground_gdk() = Gdk::Color("red");
+
+ int verse = 0;
+ string indentString = " ";
+ bool isNewline = true;
+ for(auto tex : texts) {
+ std::vector<Glib::RefPtr<Gtk::TextBuffer::Tag>> tags = {verseSize};
+ bool isParagraph = false;
+ bool isIndent = false;
+ bool isDivineName = false;
+ for(string modifier : tex.modifiers) {
+ if(modifier == "paragraph") {
+ isParagraph = true;
+ } else if (modifier == "line indent0") {
+ isIndent = true;
+ } else if (modifier == "divineName") {
+ isDivineName = true;
+ } else if (modifier == "wordsOfJesus") {
+ tags.push_back(redletter);
+ }
+ }
+ if(isIndent) {
+ isParagraph = false;
+ if(isNewline) {
+ tags.push_back(indent);
+ }
+ }
+ if(isParagraph) {
+ iter = buf->insert_with_tags(iter, indentString, tags);
+ }
+ if(tex.verse != verse) {
+ std::vector<Glib::RefPtr<Gtk::TextBuffer::Tag>> verseTags(tags.begin(), tags.end());
+ verseTags.push_back(verseScale);
+ verseTags.push_back(verseOffset);
+ iter = buf->insert_with_tags(iter, " " + std::to_string(tex.verse), verseTags);
+ }
+ verse = tex.verse;
+ if(isDivineName) {
+ // There's no small caps support. Sigh. We do fake small caps instead.
+ // Because i lazy, first letter is normal caps and rest small caps, always.
+ transform(tex.text.begin(), tex.text.end(), tex.text.begin(), ::toupper);
+ iter = buf->insert_with_tags(iter, tex.text.substr(0, 1), tags);
+ auto tag = buf->create_tag();
+ tag->property_scale() = 0.75;
+ tags.push_back(tag);
+ iter = buf->insert_with_tags(iter, tex.text.substr(1), tags);
+ } else {
+ iter = buf->insert_with_tags(iter, tex.text, tags);
+ }
+ if(tex.text.back() == '\n') {
+ isNewline = true;
+ } else {
+ isNewline = false;
+ }
+ }
+}
+
+void Sword::getConfig(string book, int chapter, struct config *conf) {
+ if(isNoMods) {
+ conf->chapter = 0;
+ conf->book = "";
+ conf->bookFull = "";
+ conf->maxChapter = 0;
+ conf->version = "";
+ } else {
+ auto passages = libbible::getPassages(defaultMod, book);
+ conf->chapter = chapter;
+ conf->book = passages[0].bookShort;
+ conf->bookFull = passages[0].book;
+ conf->maxChapter = passages.back().chapterStart;
+ conf->version = defaultMod;
+ }
+}
+
+vector<string> Sword::getBooks() {
+ if(isNoMods) {
+ return vector<string>();
+ }
+ return libbible::getModules()[defaultMod];
+}