diff options
Diffstat (limited to 'src')
38 files changed, 6672 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..7cdfd24 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,21 @@ +SUBDIRS = data pics + +INCLUDES = -I/usr/include/qt3 $(all_includes) + +kde_module_LTLIBRARIES = kio_sword.la + +kio_sword_la_SOURCES = kio_sword.cpp renderer.cpp ks_osishtml.cpp ks_gbfhtml.cpp \ + ks_thmlhtml.cpp utils.cpp swordutils.cpp swordoptions.cpp filter.cpp template.cpp + +kio_sword_la_LIBADD = -lqt-mt -lkio $(LIB_SWORD) + +kio_sword_la_LDFLAGS = -avoid-version -module $(all_libraries) $(KDE_PLUGIN) + +protocol_DATA = sword.protocol +protocoldir = $(kde_servicesdir) + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kio_sword.pot + +noinst_HEADERS = kio_sword.h renderer.h swordoptions.h ks_osishtml.h \ + ks_gbfhtml.h ks_thmlhtml.h utils.h swordutils.h option.h filter.h template.h diff --git a/src/data/Makefile.am b/src/data/Makefile.am new file mode 100644 index 0000000..486fc57 --- /dev/null +++ b/src/data/Makefile.am @@ -0,0 +1,4 @@ +kiosworddatadir = $(kde_datadir)/kio_sword +kiosworddata_DATA = kio_sword.css swordvertical.png + +EXTRA_DIST = $(kiosworddata_DATA) diff --git a/src/data/kio_sword.css b/src/data/kio_sword.css new file mode 100644 index 0000000..bf6cdb2 --- /dev/null +++ b/src/data/kio_sword.css @@ -0,0 +1,273 @@ +body { + background-color: #d0d0d0; + margin: 0px; + padding: 0px; + line-height: 1.5em; +} + + +div.page +{ + margin: 10px; +} + +div.content +{ + padding: 5px 5px 5px 25px; + margin: 0px; + background: #ffffff; + border: solid #808080 1px; + /* background-image: url('file:///usr/share/apps/kio_sword/swordvertical.png'); + background-repeat: no-repeat; + background-position: 50% 50%; */ +} + + +h1, h2, h3 { + color: #404040; +} + +h1 { + font-size: 135%; + margin-left: -15px; +} + +h2 +{ + font-size: 120%; + margin-left: -10px; +} + +h3 +{ + font-size: 110%; + margin-left: -5px; +} + +h4, h5, h6 { font-size: 100%; } + + +hr { + text-align: center ; +} + +a { + color: #4000ff; + font-weight: bold; +} + +a:link, a:visited { + text-decoration: none ; +} + +a:hover { + text-decoration: underline; +} + +div.text { + margin-bottom: 10px; +} + +td.page { + background-color: #ffffff; + width: 100%; +} + +.jesusquote { + color: red ; +} + +.versenumber { + vertical-align: super; + font-size: 0.7em ; +} + +.biblename { + text-align: right ; + color: #202020 ; + font-style: italic; + font-size: small; +} + +img.tableimg { + display: block; + margin: 0px; + padding: 0px; + border: none; +} + +.error { + font-size: 1.2em ; + color: red ; +} + +.fixme { + font-size: 1.2em ; + color: red ; +} + +h1.moduletitle, h2.moduletitle, h1.bibleref, h2.biblref { + text-align: center; +} + +h1.moduleslist { + text-align: center; +} + +/* Page links */ +div.links { + font-size: 90%; + text-align: center; + clear: both; + padding-top: 5px; +} + +div.links ul { + list-style: none; + margin: 0px; + padding: 0px; +} +div.links li { + display: inline; + margin: 0px; + padding: 0px; +} + +div.links li:before { + display: inline; + content: " | "; +} +div.links li:first-child:before { + display: inline; + content: ""; +} + +/* Page toggles */ +div.toggles { + font-size: 90%; + text-align: right; + border-bottom: 1px solid #808080; + border-left: 1px solid #808080; + border-right: 1px solid #808080; + padding-left: 2px; + padding-right: 2px; + background: #e0e0e0; +} + +div.toggles ul { + list-style: none; + margin: 0px; + padding: 0px; +} +div.toggles li { + display: inline; + margin: 0px; + padding: 0px; +} + +div.toggles li:before { + display: inline; + content: " | "; +} +div.toggles li:first-child:before { + display: inline; + content: "Toggles: "; +} + +/* Settings page */ + +table.settings { + border-top: 1px solid black; + border-left: 1px solid black; +} +table.settings td, +table.settings th { + border-right: 1px solid black; + border-bottom: 1px solid black; + margin: 0px; +} + + +table.settings th { + padding: 3pt 5pt 3pt 5pt ; + vertical-align: middle; + text-align: center; + background-color: #c0c0c0; +} + +table.settings td { + padding: 2pt 5pt 2pt 5pt; + vertical-align: top; + text-align: left; + background-color: white; +} + + +table.settings td.settingscategory { + text-align: center; + vertical-align: middle; + font-weight: bold ; + background-color: #e0e0e0; +} + +/* Search form */ + +h1.searchform { + text-align: center; +} + +div.searchform { + text-align: center; +} +div.searchform table { + margin: auto; +} + +/* Nav links */ +div.navbottom, +div.navtop { + font-size: 0.9em; + text-align: right; + margin-top: 1em; +} +div.navbottom { + padding-top: 0px; + margin-top: 0px; +} + +div.navtop { + padding-bottom: 0px; + margin-bottom: 0px; +} + +div.navtop li, +div.navbottom li { + display: inline; + margin: 0px; +} + +div.navtop li:before, +div.navbottom li:before { + content: "| "; +} + +div.navtop li.first:before, +div.navbottom li.first:before { + content: "" +} + +div.navtop ul, +div.navbottom ul { + margin-bottom: 0px; + margin-top: 0px +} + + +/* Misc */ + + +.strongs, .morph { + font-size: small; + font-style: italic; +} + diff --git a/src/data/kio_sword.css.in b/src/data/kio_sword.css.in new file mode 100644 index 0000000..4b139f2 --- /dev/null +++ b/src/data/kio_sword.css.in @@ -0,0 +1,273 @@ +body { + background-color: #d0d0d0; + margin: 0px; + padding: 0px; + line-height: 1.5em; +} + + +div.page +{ + margin: 10px; +} + +div.content +{ + padding: 5px 5px 5px 25px; + margin: 0px; + background: #ffffff; + border: solid #808080 1px; + /* background-image: url('file://@prefix@/share/apps/kio_sword/swordvertical.png'); + background-repeat: no-repeat; + background-position: 50% 50%; */ +} + + +h1, h2, h3 { + color: #404040; +} + +h1 { + font-size: 135%; + margin-left: -15px; +} + +h2 +{ + font-size: 120%; + margin-left: -10px; +} + +h3 +{ + font-size: 110%; + margin-left: -5px; +} + +h4, h5, h6 { font-size: 100%; } + + +hr { + text-align: center ; +} + +a { + color: #4000ff; + font-weight: bold; +} + +a:link, a:visited { + text-decoration: none ; +} + +a:hover { + text-decoration: underline; +} + +div.text { + margin-bottom: 10px; +} + +td.page { + background-color: #ffffff; + width: 100%; +} + +.jesusquote { + color: red ; +} + +.versenumber { + vertical-align: super; + font-size: 0.7em ; +} + +.biblename { + text-align: right ; + color: #202020 ; + font-style: italic; + font-size: small; +} + +img.tableimg { + display: block; + margin: 0px; + padding: 0px; + border: none; +} + +.error { + font-size: 1.2em ; + color: red ; +} + +.fixme { + font-size: 1.2em ; + color: red ; +} + +h1.moduletitle, h2.moduletitle, h1.bibleref, h2.biblref { + text-align: center; +} + +h1.moduleslist { + text-align: center; +} + +/* Page links */ +div.links { + font-size: 90%; + text-align: center; + clear: both; + padding-top: 5px; +} + +div.links ul { + list-style: none; + margin: 0px; + padding: 0px; +} +div.links li { + display: inline; + margin: 0px; + padding: 0px; +} + +div.links li:before { + display: inline; + content: " | "; +} +div.links li:first-child:before { + display: inline; + content: ""; +} + +/* Page toggles */ +div.toggles { + font-size: 90%; + text-align: right; + border-bottom: 1px solid #808080; + border-left: 1px solid #808080; + border-right: 1px solid #808080; + padding-left: 2px; + padding-right: 2px; + background: #e0e0e0; +} + +div.toggles ul { + list-style: none; + margin: 0px; + padding: 0px; +} +div.toggles li { + display: inline; + margin: 0px; + padding: 0px; +} + +div.toggles li:before { + display: inline; + content: " | "; +} +div.toggles li:first-child:before { + display: inline; + content: "Toggles: "; +} + +/* Settings page */ + +table.settings { + border-top: 1px solid black; + border-left: 1px solid black; +} +table.settings td, +table.settings th { + border-right: 1px solid black; + border-bottom: 1px solid black; + margin: 0px; +} + + +table.settings th { + padding: 3pt 5pt 3pt 5pt ; + vertical-align: middle; + text-align: center; + background-color: #c0c0c0; +} + +table.settings td { + padding: 2pt 5pt 2pt 5pt; + vertical-align: top; + text-align: left; + background-color: white; +} + + +table.settings td.settingscategory { + text-align: center; + vertical-align: middle; + font-weight: bold ; + background-color: #e0e0e0; +} + +/* Search form */ + +h1.searchform { + text-align: center; +} + +div.searchform { + text-align: center; +} +div.searchform table { + margin: auto; +} + +/* Nav links */ +div.navbottom, +div.navtop { + font-size: 0.9em; + text-align: right; + margin-top: 1em; +} +div.navbottom { + padding-top: 0px; + margin-top: 0px; +} + +div.navtop { + padding-bottom: 0px; + margin-bottom: 0px; +} + +div.navtop li, +div.navbottom li { + display: inline; + margin: 0px; +} + +div.navtop li:before, +div.navbottom li:before { + content: "| "; +} + +div.navtop li.first:before, +div.navbottom li.first:before { + content: "" +} + +div.navtop ul, +div.navbottom ul { + margin-bottom: 0px; + margin-top: 0px +} + + +/* Misc */ + + +.strongs, .morph { + font-size: small; + font-style: italic; +} + diff --git a/src/data/swordvertical.png b/src/data/swordvertical.png Binary files differnew file mode 100644 index 0000000..9254aaa --- /dev/null +++ b/src/data/swordvertical.png diff --git a/src/filter.cpp b/src/filter.cpp new file mode 100644 index 0000000..dabfe47 --- /dev/null +++ b/src/filter.cpp @@ -0,0 +1,35 @@ +/*************************************************************************** + File: filter.cpp + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "filter.h" + +using namespace sword; + +namespace KioSword { + class SwordOptions; + + void FilterBase::setSwordOptions(const SwordOptions* options) + { + m_swordoptions = options; + }; +} diff --git a/src/filter.h b/src/filter.h new file mode 100644 index 0000000..0c2b4e0 --- /dev/null +++ b/src/filter.h @@ -0,0 +1,39 @@ +/*************************************************************************** + File: filter.h + Project: kio-sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef KS_FILTER_H +#define KS_FILTER_H + +#include <swbasicfilter.h> + +namespace KioSword { + class SwordOptions; + + class FilterBase : public sword::SWBasicFilter { + protected: + const SwordOptions* m_swordoptions; + public: + void setSwordOptions(const SwordOptions* options); + }; +} + +#endif diff --git a/src/kio_sword.cpp b/src/kio_sword.cpp new file mode 100644 index 0000000..b0db5bc --- /dev/null +++ b/src/kio_sword.cpp @@ -0,0 +1,676 @@ +/*************************************************************************** + File: kio_sword.cpp + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + + File info: + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +// Mine +#include "renderer.h" +#include "kio_sword.h" +#include "utils.h" +#include "template.h" +#include "option.h" + +// KDE +#include <kdebug.h> +#include <kglobal.h> +#include <klocale.h> +#include <kurl.h> +#include <kstandarddirs.h> + +// Qt +#include <qcstring.h> +#include <qmap.h> + +// Standard C++ /C +#include <list> +#include <stdlib.h> + +using namespace KIO; +using std::list; +using std::vector; + + +// main -------------------------------------------------------------------------------------------------------- +extern "C" { + int kdemain(int argc, char **argv) { + KInstance instance("kio_sword"); + + kdDebug(7101) << "*** Starting kio_sword " << endl; + + if (argc != 4) { + kdDebug(7101) << + "Usage: kio_sword protocol domain-socket1 domain-socket2" + << endl; + exit(-1); + } + + KioSword::SwordProtocol slave(argv[2], argv[3]); + slave.dispatchLoop(); + + kdDebug(7101) << "*** kio_sword Done" << endl; + return 0; + } +} + +namespace KioSword +{ + class SwordOptions; + + // HTML fragments that will be initialised at run time ------------------------------------------------------------------------- + static QString search_form; + static QString help_page; + + + + SwordProtocol::SwordProtocol(const QCString & pool_socket, + const QCString & app_socket) + : SlaveBase("kio_sword", pool_socket, app_socket) + { + kdDebug() << "SwordProtocol::SwordProtocol()" << endl; + m_config = KGlobal::config(); + } + + + SwordProtocol::~SwordProtocol() + { + kdDebug() << "SwordProtocol::~SwordProtocol()" << endl; + } + + void SwordProtocol::get(const KURL & url) + { + QString modname; + QString query; + QString error; + + kdDebug() << "SwordProtocol::get(const KURL& url)" << endl; + + /* kdDebug() << "Seconds: " << url.query() << endl; + QString remoteServer = url.host(); + int remotePort = url.port(); + kdDebug() << "myURL: " << url.prettyURL() << endl; */ + + // Send the mimeType as soon as it is known + mimeType("text/html"); + + // Set user defaults from user config file + // (with internal defaults supplied if any options + // are missing from users config file) + readUserConfig(); + + // Get options/actions from URL + parseURL(url); + + if (!m_path.isEmpty() && m_path != "/") { + if (!m_path.startsWith("/")) { + // sword:xxx is a shortcut for bible verses + modname = m_options.defaultBible(); + if (modname.isEmpty()) + { + error = i18n("No default Bible has been specified."); + } + else + { + // do redirection + query = m_path; + KURL newurl(url); + newurl.setPath('/' + modname + '/' + query); + redirection(newurl); + finished(); + return; + } + } + else + { + modname = m_path.section('/', 0, 0, QString::SectionSkipEmpty); + query = m_path.section('/', 1, -1, QString::SectionSkipEmpty); + } + } + + // handle redirections first + if (m_action == REDIRECT_QUERY) { + if (!m_redirect.module.isEmpty()) + modname = m_redirect.module; + if (!m_redirect.query.isEmpty()) + query = m_redirect.query; + + if (modname.isEmpty()) { + switch (m_moduletype) { + case DEFBIBLE: + modname = m_options.defaultBible(); + error = i18n("No default Bible has been specified."); + break; + case GREEKSTRONGS: + modname = m_options.defaultGreekStrongs(); + error = i18n("No default Greek Strongs module has been specified."); + break; + case HEBREWSTRONGS: + modname = m_options.defaultHebrewStrongs(); + error = i18n("No default Hebrew Strongs module has been specified."); + break; + case GREEKMORPH: + modname = m_options.defaultGreekMorph(); + error = i18n("No default Greek morphological module has been specified."); + break; + case HEBREWMORPH: + modname = m_options.defaultHebrewMorph(); + error = i18n("No default Hebrew morphological module has been specified."); + break; + case DEFMODULETYPE_NONE: + error = i18n("No module specified."); + } + } + + if (modname.isEmpty()) { + error = "<p class='usererror'>" + error + "</p><hr />"; + m_action = QUERY; // revert back to displaying list of modules + } else { + KURL newurl(url); + // Remove anything that will trigger a redirection + newurl.removeQueryItem("module"); + newurl.removeQueryItem("query"); + newurl.removeQueryItem("testsettings"); + newurl.removeQueryItem("modtype"); + newurl.setPath('/' + modname + '/' + query); + redirection(newurl); + finished(); + return; + } + } + + // Send the data + Template* tmplt = new Template(); + tmplt->setCurrentPath(m_path); + + switch (m_action) { + case QUERY: + if (!modname.isEmpty()) { + m_renderer.moduleQuery(modname, query, m_options, tmplt); + } else { + QString body; + tmplt->setTitle(i18n("Modules - Kio-Sword")); + if (!error.isEmpty()) { + body = error; + } + body += m_renderer.listModules(m_options); + tmplt->setContent(body); + } + break; + + case SEARCH_FORM: + tmplt->setTitle(i18n("Search - Kio-Sword")); + tmplt->setContent(searchForm(m_options)); + break; + + case SEARCH_QUERY: + tmplt->setTitle(i18n("Search Results - Kio-Sword")); + tmplt->setContent(m_renderer.search(m_redirect.module, m_redirect.query, m_stype, m_options)); + break; + + case SETTINGS_FORM: + tmplt->setTitle(i18n("Settings - Kio-Sword")); + tmplt->setContent(settingsForm()); + break; + + case SETTINGS_SAVE: + tmplt->setTitle(i18n("Settings saved - Kio-Sword")); + tmplt->setContent(saveUserConfig()); + break; + + case HELP: + tmplt->setTitle(i18n("Kio-Sword Help")); + tmplt->setContent(helpPage()); + break; + + default: + break; + } + sendPage(tmplt); + delete tmplt; + + } + + + void SwordProtocol::mimetype(const KURL& url) { + mimeType("text/html"); + finished(); + } + + /* redefine data for QCStrings so we don't send the trailing + null */ + void SwordProtocol::data(const QCString& text) { + QByteArray nonull; + nonull.setRawData(text.data(), text.size()-1); + SlaveBase::data(nonull); + nonull.resetRawData(text.data(), text.size()-1); + } + + void SwordProtocol::data(const QByteArray& array) { + SlaveBase::data(array); + } + + void SwordProtocol::readUserConfig() + { + m_options.readFromConfig(m_config); + } + + QString SwordProtocol::saveUserConfig() + { + QString message; + m_options.saveToConfig(m_config); + m_config->sync(); + // search form depends on settings, so force it to be recreated + search_form.truncate(0); + message = "<p>" + i18n("Settings saved.") + "</p>"; + return message; + } + + + #define ENUM_OPTION(option, tag, v) \ + if (!strcasecmp(key, tag)) { \ + option = v; \ + } + + void SwordProtocol::parseURL(const KURL& url) + { + // Reset data members that should always be + // retrieved from URL + m_action = QUERY; + m_path = QString::null; + m_redirect.module = QString::null; + m_redirect.query = QString::null; + m_previous.module = QString::null; + m_previous.query = QString::null; + m_moduletype = DEFMODULETYPE_NONE; + + if (url.hasPath()) + m_path = url.path(); + + m_options.readFromQueryString(url.queryItems(KURL::CaseInsensitiveKeys)); + + // URLs will be encoded in UTF-8 since they are sometimes + // generated from the search form, and the browser will + // encode in UTF-8 since the whole page has UTF-8 charset + QMap<QString, QString> items = url.queryItems(KURL::CaseInsensitiveKeys, 106); + QMap<QString, QString>::const_iterator it; + QMap<QString, QString>::const_iterator it_end = items.end(); + QString val; + + const char *key; + for(it = items.begin(); it != it_end; it++) { + key = it.key().latin1(); + val = it.data(); + + if (!strcasecmp(key, "query")) { + m_redirect.query = val; + } + else if (!strcasecmp(key, "module")) { + m_redirect.module = val; + } + else if (!strcasecmp(key, "modtype")) { + if (!strcasecmp(val, "bible")) { + m_moduletype = DEFBIBLE; + m_action = REDIRECT_QUERY; + } else if (!strcasecmp(val, "greekstrongs")) { + m_moduletype = GREEKSTRONGS; + m_action = REDIRECT_QUERY; + } else if (!strcasecmp(val, "hebrewstrongs")) { + m_moduletype = HEBREWSTRONGS; + m_action = REDIRECT_QUERY; + } else if (!strcasecmp(val, "greekmorph")) { + m_moduletype = GREEKMORPH; + m_action = REDIRECT_QUERY; + } else if (!strcasecmp(val, "hebrewmorph")) { + m_moduletype = HEBREWMORPH; + m_action = REDIRECT_QUERY; + } + } + // search + else if (!strcasecmp(key, "stype")) { + if (!strcasecmp(val, "words")) { + m_stype = Renderer::SEARCH_WORDS; + } else if (!strcasecmp(val, "phrase")) { + m_stype = Renderer::SEARCH_PHRASE; + } else if (!strcasecmp(val, "regex")) { + m_stype = Renderer::SEARCH_REGEX; + } else { + m_stype = Renderer::SEARCH_WORDS; + } + } + + // Actions + else ENUM_OPTION(m_action, "help", HELP) + else ENUM_OPTION(m_action, "search", SEARCH_FORM) + else ENUM_OPTION(m_action, "searchq", SEARCH_QUERY) + else ENUM_OPTION(m_action, "settings", SETTINGS_FORM) + else ENUM_OPTION(m_action, "savesettings", SETTINGS_SAVE) + else ENUM_OPTION(m_action, "testsettings", REDIRECT_QUERY) + + else if (!strcasecmp(key, "previouspath")) { + m_previous.module = val.section('/', 0, 0, QString::SectionSkipEmpty); + m_previous.query = val.section('/', 1, -1, QString::SectionSkipEmpty); + } + } + + // Once all the URL is parsed: + if ((m_action == QUERY) && ( + !m_redirect.query.isEmpty() || !m_redirect.module.isEmpty())) + m_action = REDIRECT_QUERY; + } + + #undef ENUM_OPTION + + + void SwordProtocol::sendPage(const Template* tplt) { + data(tplt->render(m_options)); + data(QByteArray()); // empty array means we're done sending the data + finished(); + } + + /** Returns a string representing notes about an option for the settings page + */ + template <class T> + QString optionNotes(const Option<T>& option) + { + QString output; + if (!option.m_propagate) + { + output += "<sup>1</sup>"; + } + if (option.m_configName.isNull()) + { + if (output.length() > 0) + { + output += "<sup>,</sup>"; + } + output += "<sup>2</sup>"; + } + return output; + } + + + /** HTML for a boolean option */ + QString settingsBooleanOptionRow(const QString& description, const Option<bool>& option) { + static const QString boolean_option_row( + "<tr><td>%1</td><td><nobr><input type='radio' name='%2' value='1' %3>%4 <input type='radio' name='%2' value='0' %5>%6</nobr></td><td>%2, %7</td></tr>"); + return boolean_option_row + .arg(description + optionNotes(option)) + .arg(option.m_qsShortName) + .arg(option.m_qsShortName) + .arg(option.m_qsShortName) + .arg(option() ? "checked" : "") + .arg(i18n("On")) + .arg(option() ? "" : "checked") + .arg(i18n("Off")) + .arg(option.m_qsLongName); + } + /** */ + + /** HTML for a general option row + * + * @param description User visible description of option + * @param option option metadata + * @param optionList HTML containing the <option>s + * @return + */ + QString settingsGeneralOptionRow(const QString& description, const Option<QString>& option, + const QString& optionList) + { + static const QString general_option_row( + "<tr><td>%1</td><td><select name='%2'>%3</select></td><td>%4, %5</td></tr>"); + return general_option_row + .arg(description + optionNotes(option)) + .arg(option.m_qsLongName) + .arg(optionList) + .arg(option.m_qsShortName) + .arg(option.m_qsLongName); + } + + QString SwordProtocol::settingsForm() { + QString output; + QStringList modules; + QStringList::Iterator it; + QString temp; + + static const QString separator_row( + "<tr><td class='settingscategory' colspan='3'>%1</td></tr>"); + + + // Start output + output += i18n("<h1>Settings</h1>" + "<p>Select the settings using the form below. Use the 'Save settings' button to " + " save these settings to your own configuration file. 'Test settings' will return " + " you to the previous page with the options you have specified. <br>"); + + output += QString( + "<form action='sword:/' method='GET'>" + "<table class='settings' border=0 cellspacing=0>" + " <tr><th>%1</th><th>%2</th><th>%4</th></tr>") + .arg(i18n("Description")) + .arg(i18n("Value")) + .arg(i18n("URL parameter")); + + output += separator_row.arg(i18n("Formatting options")); + output += settingsBooleanOptionRow(i18n("Display verse numbers for Bible modules"), m_options.verseNumbers); + output += settingsBooleanOptionRow(i18n("Insert line breaks between Bible verses"), m_options.verseLineBreaks); + output += settingsBooleanOptionRow(i18n("Include footnotes."), m_options.footnotes); + output += settingsBooleanOptionRow(i18n("Words of Christ in red."), m_options.redWords); + output += settingsBooleanOptionRow(i18n("Display strongs numbers (for Bibles that include them)."), m_options.strongs); + output += settingsBooleanOptionRow(i18n("Display morphological tags (for Bibles that include them)."), m_options.morph); + + output += separator_row.arg(i18n("Language")); + + // Locale + QStringList locales = m_renderer.availableLocales(); + temp = ""; + for (int i = 0; i < locales.size(); i++) + { + temp += QString("<option value='%1' %3>%2</option>") + .arg(locales[i]) + .arg(locales[i]) + .arg((m_options.locale() == locales[i]) ? "selected" : ""); + } + output += settingsGeneralOptionRow(i18n("Locale"), m_options.locale, temp); + + // Formatting options + output += settingsBooleanOptionRow(i18n("Use Hebrew cantillation."), m_options.cantillation); + output += settingsBooleanOptionRow(i18n("Show Hebrew vowel points."), m_options.hebrewVowelPoints); + output += settingsBooleanOptionRow(i18n("Show Greek accents."), m_options.greekAccents); + + output += separator_row.arg(i18n("Navigation options")); + output += settingsBooleanOptionRow(i18n("Display the whole book when a Bible book is selected, instead of an index of the chapters"), + m_options.wholeBook); + output += settingsBooleanOptionRow(i18n("Display the booklist for bibles if no book is requested"), + m_options.doBibleIndex); + output += settingsBooleanOptionRow(i18n("Display an index for dictionaries if no entry is requested"), + m_options.doDictIndex); + output += settingsBooleanOptionRow(i18n("Display an index for other books if no entry is request"), + m_options.doOtherIndex); + output += settingsBooleanOptionRow(i18n("Display a full index for books that have a multiple level index, instead of just the first level"), + m_options.doFullTreeIndex); + + + // Default modules + output += separator_row.arg(i18n("Default modules")); + modules = m_renderer.moduleList(); + + vector<QString> dm_desc; + vector<Option<QString> > dm_options; + vector<QString>::size_type i; + dm_desc.push_back(i18n("Default Bible")); + dm_options.push_back(m_options.defaultBible); + + dm_desc.push_back(i18n("Default Greek Strong's Lexicon")); + dm_options.push_back(m_options.defaultGreekStrongs); + + dm_desc.push_back(i18n("Default Hebrew Strong's Lexicon")); + dm_options.push_back(m_options.defaultHebrewStrongs); + + dm_desc.push_back(i18n("Default Greek Morphological Lexicon")); + dm_options.push_back(m_options.defaultGreekMorph); + + dm_desc.push_back(i18n("Default Hebrew Morphological Lexicon")); + dm_options.push_back(m_options.defaultHebrewMorph); + + for (i = 0; i < dm_options.size(); i++) { + temp = QString("<option value='' %1> </option>") + .arg(dm_options[i]().stripWhiteSpace().isEmpty() ? "selected" : ""); + + for (it = modules.begin(); it != modules.end(); ++it ) { + temp += QString("<option value='%1' %3>%2</option>") + .arg(*it) + .arg(*it) + .arg(((*it) == dm_options[i]() ? "selected" : "")); + } + output += settingsGeneralOptionRow(dm_desc[i], dm_options[i], temp); + } + + // Misc options + output += separator_row.arg(i18n("Other options")); + output += settingsBooleanOptionRow(i18n("Make formatting options propagate. This makes Kio-Sword remember formatting settings that you have set, by propagating them in the links. (Some navigation options are always excluded from this behaviour)."), + m_options.propagate); + + output += QString("</table>"); + + output += i18n("<p>Notes:<br/>" + "1) These options never propagate<br/>" + "2) These options are never saved<br/></p>"); + + output += QString( + "<br><input type='hidden' name='module' value='%1'>" // redirection path + "<input type='hidden' name='query' value='%2'>" // redirection path + "<input type='submit' name='testsettings' value='%3'> " // "Test settings" + "<input type='submit' name='savesettings' value='%4''>" // "Save settings" + "</form>") + .arg(m_previous.module) + .arg(m_previous.query) + .arg(i18n("Test settings")) + .arg(i18n("Save settings")); + + output += i18n("<hr><h1>Stylesheet</h1>" + "<p>To further customise the appearance of the Kio-Sword page, you can make your own modified " + "version of the style sheet. " + "Simply copy the file '%1kio_sword/kio_sword.css' to $HOME/.kde/share/apps/kio_sword/ and modify it as desired. You may want to use the 'simplepage' option above to make the most of this.</p>") + .arg(KGlobal::dirs()->findResourceDir("data", "kio_sword/kio_sword.css")); // FIXME - this must always return the system dir, not users dir. + + + return output; + } + + QString SwordProtocol::helpPage() { + if (help_page.isEmpty()) { + help_page += i18n("<h1>Help</h1>" + "<p>For full documentation, see <a href=\"help:/kio_sword\">installed help files</a>.</p>" + "<p>Kio-Sword allows you to view SWORD modules (such as Bibles and commentaries) from Konqueror.\n" + " These modules must already be installed - you can download them from <a href=\"http://www.crosswire.org/\">" + "crosswire.org</a> or you can use a program such as <a href=\"http:/www.bibletime.info\">BibleTime</a> to help" + " install them." + "<h3>Quick help</h3>\n" + "<ul>\n" + " <li>To start, simply type <b><a href=\"sword:/\">sword:/</a></b> in the location bar, and follow the links like any normal web page<br /><br />\n" + " <li>You can type the exact reference in the Location bar, instead of browsing to it, e.g.<br />\n" + " <b>sword:/KJV/Hebrews 1:3-5</b> will look up Hebrews chapter 1 verses 3 to 5 in the King James Bible.<br /><br /></li>\n" + " <li>You can specify various formatting options in the URL - see <a href=\"sword:/?settings\">Settings</a> for more info.<br /><br /></li>\n" + " <li>To use your default Bible, just omit the first forward slash: <b>sword:Hebs 1:3-5</b> <br /><br /></li>\n" + " <li>You can bookmark Kio-Sword pages just like any other web page.<br /><br /></li>\n" + " <li>You can use keyboards shortcuts - press 'Ctrl' to activate 'Acess Keys' in Konqueror, \n" + " and the following shortcuts are then available:" + " <ul><li>'u' to go up</li>\n" + " <li>'n' for next section/chapter</li>\n" + " <li>'p' for previous section/chapter</li>\n" + " <li>'t' for the module list</li>\n" + " <li>'v' to toggle verse numbers</li>\n" + " <li>'l' to toggle line breaks between verses</li>\n" + " <li>'s' to toggle Strongs numbers</li>\n" + " <li>'m' to toggle morphological tags</li>\n" + " </ul>\n" + " (Depending on the context, some of these will either not be available or won't be much use).<br/><br/>" + " Also, remember the following Konqueror shortcuts to make keyboard navigation even better:<br/>" + " <b>/</b> starts find-as-you-type<br/>" + " <b>'</b> starts find-as-you-type for link text<br/>" + " </li>\n" + "</ul>\n" + "<p>Problems, comments, feature requests? Email the author. " + "<p>Author: <a href=\"mailto:[email protected]\">[email protected]</a>" + "<p>Website: <a href=\"http://lukeplant.me.uk/kio-sword/\">http://lukeplant.me.uk/kio-sword/</a>."); + } + return help_page; + } + + QString SwordProtocol::searchForm(const SwordOptions& options) { + static const QString search_form_tmpl( + "<h1 class='searchform'>%1</h1>" // title + "<div class='searchform'>" + "<form action='sword:/' method='GET'>" + " <table class='searchform'>" + " <tr>" + " <td><label for='query'>%2</label></td>" // Search terms + " <td><input type='text' name='query'></td>" + " </tr>" + " <tr>" + " <td><label for='module'>%3</label></td>" // Module + " <td><select name='module'>" + " %4</select></td>" // (list of modules) + " </tr>" + " <tr>" + " <td valign='top'><label for='stype'>%5</label></td>" // Search type + " <td><input type='radio' name='stype' value='words' checked>%6<br>" // words + " <input type='radio' name='stype' value='phrase'>%7<br>" // phrase + " <input type='radio' name='stype' value='regex'>%8" // regex + " </td>" + " </tr>" + " <tr>" + " <td colspan='2' align='center'><input type='submit' name='searchq' value='%9'></td>" // Search + " </tr>" + " </table>" + "</form>" + "</div>"); + + if (search_form.isEmpty()) { // avoid calculating this twice + QStringList modules = m_renderer.moduleList(); + QString temp; + QStringList::Iterator it; + + temp = "<option value=''></option>"; + for (it = modules.begin(); it != modules.end(); ++it ) { + temp += QString("<option value='%1' %3>%2</option>") + .arg(*it) + .arg(*it) + .arg((*it == m_options.defaultBible()) ? "selected='selected'" : ""); + } + search_form = search_form_tmpl + .arg(i18n("Search")) + .arg(i18n("Search terms")) + .arg(i18n("Module")) + .arg(temp) + .arg(i18n("Search type")) + .arg(i18n("Words")) + .arg(i18n("Phrase")) + .arg(i18n("Regular expression")) + .arg(i18n("Search")); + } + // search_form is generated once, but we need to modify + // form each time to include propagated values + QString output(search_form); + return output.replace("</form>", optionsAsHiddenFields(options) + "</form>"); + } +} diff --git a/src/kio_sword.h b/src/kio_sword.h new file mode 100644 index 0000000..469c58d --- /dev/null +++ b/src/kio_sword.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Luke Plant * + * [email protected] * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef KIOSWORD_H +#define KIOSWORD_H + +#include "utils.h" +#include "swordoptions.h" +#include "renderer.h" + +#include <kurl.h> +#include <kconfig.h> +#include <kio/slavebase.h> + +#include <qstring.h> +#include <qcstring.h> + +namespace KioSword { + class Template; + + class SwordProtocol : public KIO::SlaveBase { + + public: + SwordProtocol(const QCString & pool_socket, + const QCString & app_socket); + virtual ~SwordProtocol(); + virtual void mimetype(const KURL & url); + virtual void get(const KURL & url); + + protected: + void data(const QCString& text); + void data(const QByteArray& text); + + void parseURL(const KURL & url); + void readUserConfig(); + QString saveUserConfig(); + + void sendPage(const Template* tmplt); + + QString helpPage(); + QString pageLinks(const SwordOptions& options); + QString searchForm(const SwordOptions& options); + QString settingsForm(); + + typedef enum { QUERY, + REDIRECT_QUERY, + SEARCH_FORM, + SEARCH_QUERY, + SETTINGS_FORM, + SETTINGS_SAVE, + HELP } ActionType; + + Renderer m_renderer; + SwordOptions m_options; + ActionType m_action; + DefModuleType m_moduletype; + QString m_path; + Renderer::SearchType m_stype; + KURL m_baseurl; + + struct { + QString query; + QString module; + } m_previous; + + struct { + QString query; + QString module; + } m_redirect; + + KConfig *m_config; + + }; +} + +#endif diff --git a/src/kio_sword.lsm b/src/kio_sword.lsm new file mode 100644 index 0000000..c06ac61 --- /dev/null +++ b/src/kio_sword.lsm @@ -0,0 +1,16 @@ +Begin3 +Title: kio_sword -- Some description +Version: 0.1 +Entered-date: +Description: +Keywords: KDE Qt +Author: Luke Plant <[email protected]> +Maintained-by: Luke Plant <[email protected]> +Home-page: +Alternate-site: +Primary-site: ftp://ftp.kde.org/pub/kde/unstable/apps/utils + xxxxxx kio_sword-0.1.tar.gz + xxx kio_sword-0.1.lsm +Platform: Linux. Needs KDE +Copying-policy: GPL +End diff --git a/src/ks_gbfhtml.cpp b/src/ks_gbfhtml.cpp new file mode 100644 index 0000000..6342ba4 --- /dev/null +++ b/src/ks_gbfhtml.cpp @@ -0,0 +1,236 @@ +/*************************************************************************** + File: ks_gbfhtml.cpp + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + and CrossWire Bible Society 2003 + (file based on gbfhtmlhref.cpp and osiscgi.cpp) + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "ks_gbfhtml.h" + +#include "utils.h" + +#include <swmodule.h> +#include <utilxml.h> +#include <versekey.h> +#include <ctype.h> + +#include <stdlib.h> + +using namespace sword; + +namespace KioSword { + GBFHTML::GBFHTML() { + setTokenStart("<"); + setTokenEnd(">"); + + setTokenCaseSensitive(true); + + //addTokenSubstitute("Rf", ")</small></font>"); + addTokenSubstitute("FA", "<font color=\"#800000\">"); // for ASV footnotes to mark text + addTokenSubstitute("Rx", "</a>"); + addTokenSubstitute("FI", "<i>"); // italics begin + addTokenSubstitute("Fi", "</i>"); + addTokenSubstitute("FB", "<b>"); // bold begin + addTokenSubstitute("Fb", "</b>"); + addTokenSubstitute("FR", "<span class='jesusquote'>"); // words of Jesus begin + addTokenSubstitute("Fr", "</span>"); + addTokenSubstitute("FU", "<u>"); // underline begin + addTokenSubstitute("Fu", "</u>"); + addTokenSubstitute("FO", "<cite>"); // Old Testament quote begin + addTokenSubstitute("Fo", "</cite>"); + addTokenSubstitute("FS", "<sup>"); // Superscript begin// Subscript begin + addTokenSubstitute("Fs", "</sup>"); + addTokenSubstitute("FV", "<sub>"); // Subscript begin + addTokenSubstitute("Fv", "</sub>"); + addTokenSubstitute("TT", "<span class='title'>"); // Book title begin + addTokenSubstitute("Tt", "</span>"); + addTokenSubstitute("PP", "<cite>"); // poetry begin + addTokenSubstitute("Pp", "</cite>"); + addTokenSubstitute("Fn", "</font>"); // font end + addTokenSubstitute("CL", "<br />"); // new line + addTokenSubstitute("CM", "<br />"); // non showing comment + addTokenSubstitute("CG", ""); // ??? + addTokenSubstitute("CT", ""); // ??? + addTokenSubstitute("JR", "<div align=\"right\">"); // right align begin + addTokenSubstitute("JC", "<div align=\"center\">"); // center align begin + addTokenSubstitute("JL", "</div>"); // align end + + } + + + bool GBFHTML::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { + const char *tok; + char val[128]; + char *valto; + const char *num; + MyUserData *u = (MyUserData *)userData; + + if (!substituteToken(buf, token)) { + XMLTag tag(token); + if (!strncmp(token, "w", 1)) { + // OSIS Word (temporary until OSISRTF is done) + valto = val; + num = strstr(token, "lemma=\"x-Strongs:"); + if (num) { + for (num+=17; ((*num) && (*num != '\"')); num++) + *valto++ = *num; + *valto = 0; + if (atoi((!isdigit(*val))?val+1:val) < 5627) { + buf += " <span class='strongs'><<a href=\""; + buf += swordUrlForSearch(GREEKSTRONGS, val, m_swordoptions).utf8(); + buf += "\">"; + for (tok = (!isdigit(*val))?val+1:val; *tok; tok++) + buf += *tok; + buf += "</a>></span> "; + //cout << buf; + + } + /* forget these for now + else { + // verb morph + sprintf(wordstr, "%03d", word-1); + module->getEntryAttributes()["Word"][wordstr]["Morph"] = val; + } + */ + } + valto = val; + num = strstr(token, "morph=\"x-Robinson:"); + if (num) { + for (num+=18; ((*num) && (*num != '\"')); num++) + *valto++ = *num; + *valto = 0; + buf += " <span class='morph'>(<a href=\""; + buf += swordUrlForSearch(GREEKMORPH, val, m_swordoptions).utf8(); + buf += "\">"; + for (tok = val; *tok; tok++) + //if(*tok != '\"') + buf += *tok; + buf += "</a>)</span> "; + } + } + + else if (!strncmp(token, "WG", 2) || !strncmp(token, "WH", 2)) { // strong's numbers + buf += " <span class='strongs'><<a href=\""; + buf += swordUrlForSearch(GREEKSTRONGS, token + 2, m_swordoptions).utf8(); + buf += "\">"; + for (tok = token + 2; *tok; tok++) + //if(token[i] != '\"') + buf += *tok; + buf += "</a>></span> "; + } + + else if (!strncmp(token, "WTG", 3) || !strncmp(token, "WTH", 3)) { // strong's numbers tense + buf += " <span class='morph'>(<a href=\""; + buf += swordUrlForSearch(GREEKMORPH, token + 3, m_swordoptions).utf8(); + buf += "\">"; + for (tok = token + 3; *tok; tok++) + if(*tok != '\"') + buf += *tok; + buf += "</a>)</span> "; + } + + else if (!strncmp(token, "WT", 2) && strncmp(token, "WTH", 3) && strncmp(token, "WTG", 3)) { // morph tags + buf += " <span class='morph'>(<a href=\""; + buf += swordUrlForSearch(GREEKMORPH, token + 2, m_swordoptions).utf8(); + buf += "\">"; + for (tok = token + 2; *tok; tok++) + if(*tok != '\"') + buf += *tok; + buf += "</a>)</span>"; + } + + else if (!strcmp(tag.getName(), "RX")) { + buf += "<a href=\""; + buf += swordUrlForSearch(DEFBIBLE, token + 3, m_swordoptions); + + /* FIXME - restore this, work out what it does + for (tok = token + 3; *tok; tok++) { + if(*tok != '<' && *tok+1 != 'R' && *tok+2 != 'x') { + buf += *tok; + } else { + break; + } + }*/ + buf += "\">"; + } + + // FIXME - modify for Kio-Sword + else if (!strcmp(tag.getName(), "RF")) { + SWBuf type = tag.getAttribute("type"); + SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) { } + if (vkey) { + // leave this special osis type in for crossReference notes types? Might thml use this some day? Doesn't hurt. + //char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n'); + buf.appendFormatted("<a href=\"noteID=%s.%c.%s\"><small><sup>*%c</sup></small></a> ", vkey->getText(), 'n', footnoteNumber.c_str(), 'n'); + } + u->suspendTextPassThru = true; + } + else if (!strcmp(tag.getName(), "Rf")) { + u->suspendTextPassThru = false; + } + /* + else if (!strncmp(token, "RB", 2)) { + buf += "<i> "; + u->hasFootnotePreTag = true; + } + + else if (!strncmp(token, "Rf", 2)) { + buf += " <a href=\"note="; + buf += u->lastTextNode.c_str(); + buf += "\">"; + buf += "<small><sup>*n</sup></small></a> "; + // let's let text resume to output again + u->suspendTextPassThru = false; + } + + else if (!strncmp(token, "RF", 2)) { + if (u->hasFootnotePreTag) { + u->hasFootnotePreTag = false; + buf += "</i> "; + } + u->suspendTextPassThru = true; + } + */ + else if (!strncmp(token, "FN", 2)) { + buf += "<font face=\""; + for (tok = token + 2; *tok; tok++) + if(*tok != '\"') + buf += *tok; + buf += "\">"; + } + + else if (!strncmp(token, "CA", 2)) { // ASCII value + buf += (char)atoi(&token[2]); + } + + else { + return false; + } + } + return true; + } +} diff --git a/src/ks_gbfhtml.h b/src/ks_gbfhtml.h new file mode 100644 index 0000000..998bdb9 --- /dev/null +++ b/src/ks_gbfhtml.h @@ -0,0 +1,54 @@ +/*************************************************************************** + File: ks_gbfhtml.h + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + and CrossWire Bible Society 2003 + (file based on gbfhtmlhref.h) + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + + +#ifndef KS_GBFHTML_H +#define KS_GBFHTML_H + +#include "filter.h" + +#include <swbasicfilter.h> +#include <swkey.h> +#include <swmodule.h> + +namespace KioSword { + /** this filter converts GBF text to HTML text with hrefs + */ + class GBFHTML : public FilterBase { + protected: + class MyUserData : public sword::BasicFilterUserData { + public: + MyUserData(const sword::SWModule *module, const sword::SWKey *key) : BasicFilterUserData(module, key) {} + bool hasFootnotePreTag; + }; + virtual sword::BasicFilterUserData *createUserData(const sword::SWModule *module, const sword::SWKey *key) { + return new MyUserData(module, key); + } + virtual bool handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData); + public: + GBFHTML(); + }; +} +#endif diff --git a/src/ks_osishtml.cpp b/src/ks_osishtml.cpp new file mode 100644 index 0000000..973a627 --- /dev/null +++ b/src/ks_osishtml.cpp @@ -0,0 +1,358 @@ +/*************************************************************************** + File: ks_osishtml.cpp + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + and CrossWire Bible Society 2003 + (file based on osishtmlhref.cpp and osiscgi.cpp) + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "ks_osishtml.h" +#include "utils.h" + +#include <utilxml.h> +#include <versekey.h> +#include <swmodule.h> + +#include <qstring.h> + +#include <stdlib.h> + +using namespace sword; + +namespace KioSword { + OSISHTML::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) { + osisQToTick = ((!module->getConfigEntry("OSISqToTick")) || (strcmp(module->getConfigEntry("OSISqToTick"), "false"))); + } + + + OSISHTML::OSISHTML() { + setTokenStart("<"); + setTokenEnd(">"); + + setEscapeStart("&"); + setEscapeEnd(";"); + + setEscapeStringCaseSensitive(true); + + addEscapeStringSubstitute("amp", "&"); + addEscapeStringSubstitute("apos", "'"); + addEscapeStringSubstitute("lt", "<"); + addEscapeStringSubstitute("gt", ">"); + addEscapeStringSubstitute("quot", "\""); + addTokenSubstitute("lg", "<br />"); + addTokenSubstitute("/lg", "<br />"); + + setTokenCaseSensitive(true); + } + + + bool OSISHTML::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { + // manually process if it wasn't a simple substitution + if (!substituteToken(buf, token)) { + MyUserData *u = (MyUserData *)userData; + XMLTag tag(token); + + // <w> tag + if (!strcmp(tag.getName(), "w")) { + if ((!tag.isEmpty()) && (!tag.isEndTag())) { + // start <w> tag + u->w = token; + } else { + // end <w> tag + const char *attrib; + const char *val; + if (tag.isEndTag()) + tag = u->w.c_str(); + + if ((attrib = tag.getAttribute("xlit"))) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" %s", val); + } + if ((attrib = tag.getAttribute("gloss"))) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" %s", val); + } + if ((attrib = tag.getAttribute("lemma"))) { + int count = tag.getAttributePartCount("lemma"); + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + do { + attrib = tag.getAttribute("lemma", i); + if (i < 0) i = 0; // to handle our -1 condition + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + if (*val == 'G') { + buf.append(QString(" <span class='strongs'><<a href=\"%2\">%1</a>></span> ") + .arg(val+1) + .arg(swordUrlForSearch(GREEKSTRONGS, val+1, m_swordoptions)) + .utf8()); + } else if (*val == 'H') { + buf.append(QString(" <span class='strongs'><<a href=\"%2\">%1</a>></span> ") + .arg(val+1) + .arg(swordUrlForSearch(HEBREWSTRONGS, val+1, m_swordoptions)) + .utf8()); + } + } while (++i < count); + } + if ((attrib = tag.getAttribute("morph"))) { + int count = tag.getAttributePartCount("morph"); + int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 + do { + attrib = tag.getAttribute("morph", i); + if (i < 0) i = 0; // to handle our -1 condition + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + if (!strncmp(attrib, "x-Robinson",10)) { //robinson codes + buf.append(QString(" <span class='morph'>(<a href=\"%2\">%1</a>)</span> ") + .arg(val) + .arg(swordUrlForSearch(GREEKMORPH, val, m_swordoptions)) + .utf8()); + } else if ((*val == 'T')) { + if (val[1] == 'G') { + buf.append(QString(" <span class='morph'>(<a href=\"%2\">%1</a>)</span> ") + .arg(val+1) + .arg(swordUrlForSearch(GREEKMORPH, val+1, m_swordoptions)) + .utf8()); + } else if (val[1] == 'H') { + buf.append(QString(" <span class='morph'>(<a href=\"%2\">%1</a>)</span> ") + .arg(val+1) + .arg(swordUrlForSearch(HEBREWMORPH, val+1, m_swordoptions)) + .utf8()); + } + } + } while (++i < count); + } + if ((attrib = tag.getAttribute("POS"))) { + val = strchr(attrib, ':'); + val = (val) ? (val + 1) : attrib; + buf.appendFormatted(" %s", val); + } + } + } + + // <note> tag + // FIXME - needs to be modified for Kio-Sword + else if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + SWBuf type = tag.getAttribute("type"); + + if (type != "strongsMarkup") { // leave strong's markup notes out, in the future we'll probably have different option filters to turn different note types on or off + SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) { } + if (vkey) { + char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n'); + buf.appendFormatted("<a href=\"noteID=%s.%c.%s\"><small><sup>*%c</sup></small></a> ", vkey->getText(), ch, footnoteNumber.c_str(), ch); + } + } + u->suspendTextPassThru = true; + } + } + if (tag.isEndTag()) { + u->suspendTextPassThru = false; + } + } + + // <p> paragraph tag + else if (!strcmp(tag.getName(), "p")) { + if ((!tag.isEndTag()) && (!tag.isEmpty())) { // non-empty start tag + buf += "<p>"; + } + else if (tag.isEndTag()) { // end tag + buf += "</P>"; + userData->supressAdjacentWhitespace = true; + } + else { // empty paragraph break marker + buf += "<br />"; + userData->supressAdjacentWhitespace = true; + } + } + + // FIXME - needs to be modified for Kio-Sword + // <reference> tag + else if (!strcmp(tag.getName(), "reference")) { + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + buf += "<a href=\"\">"; + } + else if (tag.isEndTag()) { + buf += "</a>"; + } + } + + // <l> poetry, etc + else if (!strcmp(tag.getName(), "l")) { + if (tag.isEmpty()) { + buf += "<br />"; + } + else if (tag.isEndTag()) { + buf += "<br />"; + } + else if (tag.getAttribute("sID")) { // empty line marker + buf += "<br />"; + } + } + + // <milestone type="line"/> + else if ((!strcmp(tag.getName(), "milestone")) && (tag.getAttribute("type")) && (!strcmp(tag.getAttribute("type"), "line"))) { + buf += "<br />"; + userData->supressAdjacentWhitespace = true; + } + + // <title> + else if (!strcmp(tag.getName(), "title")) { + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + buf += "<div class='title'>"; + } + else if (tag.isEndTag()) { + buf += "</div>"; + } + } + + // <hi> hi? hi contrast? + else if (!strcmp(tag.getName(), "hi")) { + SWBuf type = tag.getAttribute("type"); + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + if (type == "b" || type == "x-b") { + buf += "<b>"; + u->inBold = true; + } + else { // all other types + buf += "<i>"; + u->inBold = false; + } + } + else if (tag.isEndTag()) { + if(u->inBold) { + buf += "</b>"; + u->inBold = false; + } + else + buf += "</i>"; + } + else { // empty hi marker + // what to do? is this even valid? + } + } + + // <q> quote + else if (!strcmp(tag.getName(), "q")) { + SWBuf type = tag.getAttribute("type"); + SWBuf who = tag.getAttribute("who"); + const char *lev = tag.getAttribute("level"); + int level = (lev) ? atoi(lev) : 1; + + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + /*buf += "{";*/ + + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + + if (who == "Jesus") + buf += "<span class='jesusquote'>"; + else + buf += "<span class='quote'>"; + } + else if (tag.isEndTag()) { + buf += "</span>"; + + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + + } + else { // empty quote marker + //alternate " and ' + if (u->osisQToTick) + buf += (level % 2) ? '\"' : '\''; + } + } + + // <transChange> + else if (!strcmp(tag.getName(), "transChange")) { + SWBuf type = tag.getAttribute("type"); + + if ((!tag.isEndTag()) && (!tag.isEmpty())) { + + // just do all transChange tags this way for now + // if (type == "supplied") + buf += "<i>"; + } + else if (tag.isEndTag()) { + buf += "</i>"; + } + else { // empty transChange marker? + } + } + + // FIXME - remove for Kio-Sword? + // image + else if (!strcmp(tag.getName(), "figure")) { + const char *src = tag.getAttribute("src"); + if (!src) // assert we have a src attribute + return false; + + char* filepath = new char[strlen(u->module->getConfigEntry("AbsoluteDataPath")) + strlen(token)]; + *filepath = 0; + strcpy(filepath, userData->module->getConfigEntry("AbsoluteDataPath")); + strcat(filepath, src); + + // we do this because BibleCS looks for this EXACT format for an image tag + buf+="<image src=\""; + buf+=filepath; + buf+="\" />"; + /* + char imgc; + for (c = filepath + strlen(filepath); c > filepath && *c != '.'; c--); + c++; + FILE* imgfile; + if (strcasecmp(c, "jpg") || stricmp(c, "jpeg")) { + imgfile = fopen(filepath, "r"); + if (imgfile != NULL) { + buf += "{\\nonshppict {\\pict\\jpegblip "; + while (feof(imgfile) != EOF) { + buf.appendFormatted("%2x", fgetc(imgfile)); + } + fclose(imgfile); + buf += "}}"; + } + } + else if (strcasecmp(c, "png")) { + buf += "{\\*\\shppict {\\pict\\pngblip "; + + buf += "}}"; + } + */ + delete [] filepath; + } + + else { + return false; // we still didn't handle token + } + } + return true; + } +} diff --git a/src/ks_osishtml.h b/src/ks_osishtml.h new file mode 100644 index 0000000..108f98e --- /dev/null +++ b/src/ks_osishtml.h @@ -0,0 +1,60 @@ +/*************************************************************************** + File: ks_osishtml.h + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + and CrossWire Bible Society 2003 + (file based on osishtmlhref.h) + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef KS_OSISHTML_H +#define KS_OSISHTML_H + +#include "filter.h" + +#include <swbasicfilter.h> +#include <swkey.h> +#include <swmodule.h> + +using namespace sword; + +namespace KioSword { + /** this filter converts OSIS text to HTML text with hrefs */ + class OSISHTML : public FilterBase { + private: + protected: + class MyUserData : public sword::BasicFilterUserData { + public: + bool osisQToTick; + bool inBold; + sword::SWBuf lastTransChange; + sword::SWBuf w; + sword::SWBuf fn; + MyUserData(const sword::SWModule *module, const sword::SWKey *key); + }; + virtual BasicFilterUserData* createUserData(const sword::SWModule *module, const sword::SWKey *key) { + return new MyUserData(module, key); + } + virtual bool handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData); + public: + OSISHTML(); + }; +} + +#endif diff --git a/src/ks_thmlhtml.cpp b/src/ks_thmlhtml.cpp new file mode 100644 index 0000000..2ee3175 --- /dev/null +++ b/src/ks_thmlhtml.cpp @@ -0,0 +1,222 @@ +/*************************************************************************** + File: ks_thmlhtml.cpp + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + and CrossWire Bible Society 2001 + (file based on thmlhtmlhref.cpp) + and the BibleTime team (bits taken from bt_thmlhtml.cpp) + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "ks_thmlhtml.h" + +#include "utils.h" + +#include <swmodule.h> +#include <utilxml.h> +#include <versekey.h> + +#include <stdlib.h> + +using namespace sword; + +namespace KioSword { + ThMLHTML::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) { + if (module) { + version = module->Name(); + BiblicalText = (!strcmp(module->Type(), "Biblical Texts")); + } + } + + + ThMLHTML::ThMLHTML() { + setTokenStart("<"); + setTokenEnd(">"); + + setTokenCaseSensitive(true); + addTokenSubstitute("scripture", "<i> "); + addTokenSubstitute("/scripture", "</i> "); + } + + + bool ThMLHTML::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { + const char *tok; + if (!substituteToken(buf, token)) { // manually process if it wasn't a simple substitution + MyUserData *u = (MyUserData *)userData; + + XMLTag tag(token); + if ((!tag.isEndTag()) && (!tag.isEmpty())) + u->startTag = tag; + + if (tag.getName() && !strcasecmp(tag.getName(), "sync")) { //lemmas, morph codes or strongs + if (tag.getAttribute("type") && !strcasecmp(tag.getAttribute("type"), "lemma")) { // Lemma + const char *value = tag.getAttribute("value"); + if (strlen(value)) { + buf.appendFormatted + (" <span class='lemma'><%s></span>", value); + } + } else if (tag.getAttribute("type") && !strcasecmp(tag.getAttribute("type"), "morph")) { // Morph + const char *value = tag.getAttribute("value"); + if (value) { + buf.append(QString(" <span class='morph'>(<a href=\"%2\">%1</a>)</span>") + .arg(value) + .arg(swordUrlForSearch(GREEKMORPH, value, m_swordoptions)) + .utf8()); + } + } else if (tag.getAttribute("type") && !strcasecmp(tag.getAttribute("type"), "Strongs")) { // Strongs + const char *value = + tag.getAttribute("value"); + if (value && value[0] == 'H') { // hewbrew strongs number + // value + 1 => skip the H + buf.append(QString(" <span class='strongs'><<a href=\"%2\">%1</a>></span>") + .arg(value + 1) + .arg(swordUrlForSearch(HEBREWSTRONGS, value + 1, m_swordoptions)) + .utf8()); + } else if (value && value[0] == 'G') { //greek strongs number + // value + 1 => skip the G + buf.append(QString(" <span class='strongs'><<a href=\"%2\">%1</a>></span>") + .arg(value + 1) + .arg(swordUrlForSearch(GREEKSTRONGS, value + 1, m_swordoptions)) + .utf8()); + } + } + } + // FIXME - modify for Kio-Sword + // <note> tag + else if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + SWBuf type = tag.getAttribute("type"); + SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) { } + if (vkey) { + // leave this special osis type in for crossReference notes types? Might thml use this some day? Doesn't hurt. + char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n'); + buf.appendFormatted("<a href=\"noteID=%s.%c.%s\"><small><sup>*%c</sup></small></a> ", vkey->getText(), ch, footnoteNumber.c_str(), ch); + } + u->suspendTextPassThru = true; + } + } + if (tag.isEndTag()) { + u->suspendTextPassThru = false; + } + } + // <scripRef> tag + else if (!strcmp(tag.getName(), "scripRef")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + u->suspendTextPassThru = true; + } + } + if (tag.isEndTag()) { // </scripRef> + if (!u->BiblicalText) { + SWBuf refList = u->startTag.getAttribute("passage"); + if (!refList.length()) + refList = u->lastTextNode; + SWBuf version = tag.getAttribute("version"); + buf += "<a href=\""; + buf += swordUrlForSearch(DEFBIBLE, refList.c_str(), m_swordoptions).utf8(); + /* TODO - can we do with in KioSword? + if (version.length()) { + buf += "&version="; + buf += version; + buf += " "; + }*/ + buf += "\">"; + buf += u->lastTextNode.c_str(); + buf += "</a>"; + } + // FIXME for Kio-Sword + else { + SWBuf footnoteNumber = u->startTag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) {} + if (vkey) { + // leave this special osis type in for crossReference notes types? Might thml use this some day? Doesn't hurt. + buf.appendFormatted("<a href=\"noteID=%s.x.%s\"><small><sup>*x</sup></small></a> ", vkey->getText(), footnoteNumber.c_str()); + } + } + + // let's let text resume to output again + u->suspendTextPassThru = false; + } + } + else if (tag.getName() && !strcasecmp(tag.getName(), "div")) { + if (tag.isEndTag() && u->SecHead) { + buf += "</i></b><br />"; + u->SecHead = false; + } + else if (tag.getAttribute("class")) { + if (!strcasecmp(tag.getAttribute("class"), "sechead")) { + u->SecHead = true; + buf += "<br /><b><i>"; + } + else if (!strcasecmp(tag.getAttribute("class"), "title")) { + u->SecHead = true; + buf += "<br /><b><i>"; + } + } + } + else if (tag.getName() && (!strcasecmp(tag.getName(), "img") || !strcasecmp(tag.getName(), "image"))) { + const char *src = strstr(token, "src"); + if (!src) // assert we have a src attribute + return false; + + buf += '<'; + for (const char *c = token; *c; c++) { + if (c == src) { + for (;((*c) && (*c != '"')); c++) + buf += *c; + + if (!*c) { c--; continue; } + + buf += '"'; + if (*(c+1) == '/') { + buf += "file:"; + buf += userData->module->getConfigEntry("AbsoluteDataPath"); + if (buf[buf.length()-2] == '/') + c++; // skip '/' + } + continue; + } + buf += *c; + } + buf += '>'; + } + else { + buf += '<'; + /*for (const char *tok = token; *tok; tok++) + buf += *tok;*/ + buf += token; + buf += '>'; + //return false; // we still didn't handle token + } + } + return true; + } +} diff --git a/src/ks_thmlhtml.h b/src/ks_thmlhtml.h new file mode 100644 index 0000000..8d877c2 --- /dev/null +++ b/src/ks_thmlhtml.h @@ -0,0 +1,58 @@ +/*************************************************************************** + File: ks_thmlhtml.cpp + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + and CrossWire Bible Society 2001 + (file based on thmlhtmlhref.cpp) + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef KS_THMLHTML_H +#define KS_THMLHTML_H + +#include "filter.h" + +#include <swbasicfilter.h> +#include <utilxml.h> +#include <swkey.h> +#include <swmodule.h> + +namespace KioSword { + /** this filter converts ThML text to HTML text with hrefs + */ + class ThMLHTML : public FilterBase { + protected: + class MyUserData : public sword::BasicFilterUserData { + public: + MyUserData(const sword::SWModule *module, const sword::SWKey *key); + sword::SWBuf inscriptRef; + bool SecHead; + bool BiblicalText; + sword::SWBuf version; + sword::XMLTag startTag; + }; + virtual sword::BasicFilterUserData* createUserData(const sword::SWModule *module, const sword::SWKey *key) { + return new MyUserData(module, key); + } + virtual bool handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData); + public: + ThMLHTML(); + }; +} +#endif /* KS_THMLHTML_H */ diff --git a/src/option.h b/src/option.h new file mode 100644 index 0000000..2c146ba --- /dev/null +++ b/src/option.h @@ -0,0 +1,300 @@ +/*************************************************************************** + File: option.h + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef option_h +#define option_h + +#include <kconfig.h> + +#include <qstring.h> +#include <qmap.h> + +namespace KioSword +{ + class OptionBase + { + public: + virtual void readFromQueryString(QMap<QString, QString> params, bool allowPropagating) = 0; + virtual void getQueryStringPair(QString& name, QString& val) = 0; + virtual void readFromConfig(const KConfig* config) = 0; + virtual void saveToConfig(KConfig* config) = 0; + virtual void copy(const OptionBase* other) = 0; + + virtual ~OptionBase() {}; + }; + + /** + * Template class for options that can be read/saved to a query string + * or config file and are used at run time to determine various things + * + */ + template <class T> + class Option : public OptionBase + { + protected: + T m_value; // current value + T m_propagate_value; // value we are going to propagate when creating URLs + T m_default_value; // KioSWord internal default + T m_config_value; // User's default + + /** Convert a value from a string to the option's type */ + static const T fromString(const QString& val) + { + // We will specialise this function later + // to work correctly + T result; + return result; + } + + /** Convert the option to a string for use in query strings */ + QString toString(T val) + { + // Will specialise this later + QString result; + return result; + } + + /** return the config setting */ + T readConfigSetting(const KConfig* config) + { + // We will specialise this later + T result; + return result; + } + + public: + QString m_qsShortName; // short name in querystring + QString m_qsLongName; // long name in querystring + bool m_propagate; // true if this option can be propagated + QString m_configName; // name of config setting in config file + + Option() + { + }; + + virtual ~Option() + { + }; + + /** + * Sets up the names and default value of the option + * + * Setting configName to "" means the option is never put into the config file + * Setting both qsShortName and qsLongName to "" means the option is never put + * in the query string. + * + * @param default_value the value the option if not set from anywhere else + * @param configName the name the option has in the config file, or "" to never save or read from config + * @param qsShortName the short name for the option when used in a query string + * @param qsLongName the long name for the option when use in a query string + * @param propagate true if this parameter can be propagated in generated query strings + */ + void setup(const T& default_value, const QString& configName, const QString& qsShortName, const QString& qsLongName, bool propagate) + { + m_value = default_value; + m_default_value = default_value; + m_config_value = default_value; // assume this for now + m_propagate_value = m_value; + m_configName = configName; + m_qsShortName = qsShortName; + m_qsLongName = qsLongName; + m_propagate = propagate; + } + + /** Get the value of the option */ + const T& operator() () const + { + return m_value; + } + + /** Set the value of the option (including the value to propagate) */ + void set(const T& value) + { + m_value = value; + m_propagate_value = value; + } + + /** read and set the option from the querystring */ + virtual void readFromQueryString(QMap<QString, QString> params, bool allowPropagating) + { + T newval; + bool found = false; + +/* // Start with defaults. We have to do this + // because these objects are re-used from one request to the next + m_value = m_config_value; + m_propagate_value = m_config_value;*/ + + // Search for short name + QMap<QString, QString>::const_iterator it = params.find(m_qsShortName); + if (it != params.end()) + { + newval = fromString(it.data()); + found = true; + } + if (!found) { + // Search for long name + it = params.find(m_qsLongName); + if (it != params.end()) + { + newval = fromString(it.data()); + found = true; + } + } + if (found) { + m_value = newval; + if (m_propagate && allowPropagating) { + m_propagate_value = newval; + } + } + } + + /** set the name and value of a query string pair */ + virtual void getQueryStringPair(QString& name, QString& val) + { + // To keep things tidy, we don't propagate in the + // query string values that wouldn't make a difference + // i.e. if current value is the same as config, + // don't propagate + if (m_propagate_value != m_config_value) { + if (m_qsShortName.isEmpty()) + name.append(m_qsLongName); + else + name.append(m_qsShortName.copy()); + val.append(toString(m_propagate_value)); + } + } + + /** read and set the value from the config file, or set to default if no config setting */ + virtual void readFromConfig(const KConfig* config) + { + if (!m_configName.isEmpty()) + { + set(readConfigSetting(config)); + } + else + { + set(m_default_value); + } + m_config_value = m_value; + } + + /** save the value to the config file */ + virtual void saveToConfig(KConfig* config) + { + if (!m_configName.isEmpty()) + { + // overloads for KConfig::writeEntry cater + // for everything we need so far + if (m_value != m_default_value) // keep settings file tidy + { + config->writeEntry(m_configName, m_value); + m_config_value = m_value; + } + else + { + config->deleteEntry(m_configName); + } + } + } + + /** copy value from another */ + virtual void copy(const OptionBase* other) + { + // we must ensure that we only copy from an object + // of the same type. + const Option<T>* other2 = (Option<T>*)other; + + // m_configName, m_default_value, m_qsShortName and m_qsLongName, and m_propagate + // have already been set up correctly (those don't change fromString + // the values given in the setup() method) + m_value = other2->m_value; + m_config_value = other2->m_config_value; + m_propagate_value = other2->m_propagate_value; + } + }; + + // Specialisations + + // fromString specialisations + template<> + inline const bool Option<bool>::fromString(const QString& val) + { + if (val == "0") + return false; + else + return true; + } + + template<> + inline const QString Option<QString>::fromString(const QString& val) + { + return val; + } + + template<> + inline const int Option<int>::fromString(const QString& val) + { + return val.toInt(); + } + + // toString specialisations + template<> + inline QString Option<bool>::toString(bool val) + { + return val ? QString("1"): QString("0"); + } + + template<> + inline QString Option<QString>::toString(QString val) + { + return val; + } + + template<> + inline QString Option<int>::toString(int val) + { + return QString::number(val); + } + + // readConfigSetting specialisations + template<> + inline bool Option<bool>::readConfigSetting(const KConfig* config) + { + return config->readBoolEntry(m_configName, m_default_value); + } + + template<> + inline QString Option<QString>::readConfigSetting(const KConfig* config) + { + return config->readEntry(m_configName, m_default_value); + } + + template<> + inline int Option<int>::readConfigSetting(const KConfig* config) + { + return config->readNumEntry(m_configName, m_default_value); + } +} + +#endif diff --git a/src/pics/Makefile.am b/src/pics/Makefile.am new file mode 100644 index 0000000..7fb5403 --- /dev/null +++ b/src/pics/Makefile.am @@ -0,0 +1,11 @@ +KDE_ICON = kio_sword + +EXTRA_DIST = kio_sword_everything.svg \ + kio_sword_borders.xcf \ + hisc-app-kio_sword.svgz \ + hi128-app-kio_sword.png \ + hi64-app-kio_sword.png \ + hi48-app-kio_sword.png \ + hi32-app-kio_sword.png \ + hi22-app-kio_sword.png \ + hi16-app-kio_sword.png diff --git a/src/pics/hi128-app-kio_sword.png b/src/pics/hi128-app-kio_sword.png Binary files differnew file mode 100644 index 0000000..dc3f665 --- /dev/null +++ b/src/pics/hi128-app-kio_sword.png diff --git a/src/pics/hi16-app-kio_sword.png b/src/pics/hi16-app-kio_sword.png Binary files differnew file mode 100644 index 0000000..6897bdc --- /dev/null +++ b/src/pics/hi16-app-kio_sword.png diff --git a/src/pics/hi22-app-kio_sword.png b/src/pics/hi22-app-kio_sword.png Binary files differnew file mode 100644 index 0000000..c4da37d --- /dev/null +++ b/src/pics/hi22-app-kio_sword.png diff --git a/src/pics/hi32-app-kio_sword.png b/src/pics/hi32-app-kio_sword.png Binary files differnew file mode 100644 index 0000000..63db51d --- /dev/null +++ b/src/pics/hi32-app-kio_sword.png diff --git a/src/pics/hi48-app-kio_sword.png b/src/pics/hi48-app-kio_sword.png Binary files differnew file mode 100644 index 0000000..2175625 --- /dev/null +++ b/src/pics/hi48-app-kio_sword.png diff --git a/src/pics/hi64-app-kio_sword.png b/src/pics/hi64-app-kio_sword.png Binary files differnew file mode 100644 index 0000000..cf970ff --- /dev/null +++ b/src/pics/hi64-app-kio_sword.png diff --git a/src/pics/hisc-app-kio_sword.svgz b/src/pics/hisc-app-kio_sword.svgz Binary files differnew file mode 100644 index 0000000..fff5113 --- /dev/null +++ b/src/pics/hisc-app-kio_sword.svgz diff --git a/src/pics/kio_sword_borders.xcf b/src/pics/kio_sword_borders.xcf Binary files differnew file mode 100644 index 0000000..5756d2b --- /dev/null +++ b/src/pics/kio_sword_borders.xcf diff --git a/src/pics/kio_sword_everything.svg b/src/pics/kio_sword_everything.svg new file mode 100644 index 0000000..5218535 --- /dev/null +++ b/src/pics/kio_sword_everything.svg @@ -0,0 +1,1879 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" +"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Created with Sodipodi ("http://www.sodipodi.com/") --> +<svg + width="144pt" + height="144pt" + viewBox="0 0 144 144" + xml:space="preserve" + id="svg574" + sodipodi:version="0.32" + inkscape:version="0.39cvs" + sodipodi:docname="kio_sword_everything.svg" + sodipodi:docbase="/home/luke/my_devel/kio_sword/src/pics" + xmlns="http://www.w3.org/2000/svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xml="http://www.w3.org/XML/1998/namespace" + xmlns:xlink="http://www.w3.org/1999/xlink"><defs + id="defs1077"><linearGradient + id="linearGradient1097"> + <text + id="text563" /> + + <stop + style="stop-color:#7347ba;stop-opacity:1.0000;" + offset="0" + id="stop1099" /> + + <text + id="text565" /> + + <stop + style="stop-color:#000c46;stop-opacity:1.0000;" + offset="1" + id="stop1101" /> + + <text + id="text567" /> + + </linearGradient> +<linearGradient + id="linearGradient2334"> + <stop + offset="0.0000000" + style="stop-color:#868686;stop-opacity:1.0000000;" + id="stop2336" /> + + + + + <stop + offset="1.0000000" + style="stop-color:#6b6b6b;stop-opacity:1.0000000;" + id="stop2338" /> + + + + + </linearGradient> + + + <linearGradient + id="linearGradient2925"> + <stop + offset="0.00000000" + style="stop-color:#7247ba;stop-opacity:1;" + id="stop2926" /> + + + + + <stop + offset="1.00000000" + style="stop-color:#000c46;stop-opacity:1;" + id="stop2927" /> + + + + + </linearGradient> + + + + + <linearGradient + id="linearGradient2922"> + <stop + offset="0.00000000" + style="stop-color:#85682b;stop-opacity:1;" + id="stop2923" /> + + + + + <stop + offset="1.00000000" + style="stop-color:#c59e47;stop-opacity:1;" + id="stop2924" /> + + + + + </linearGradient> + + + + + <linearGradient + id="linearGradient2903"> + <stop + offset="0.00000000" + style="stop-color:#572e00;stop-opacity:1;" + id="stop2904" /> + + + + + <stop + offset="1.00000000" + style="stop-color:#b5a278;stop-opacity:1;" + id="stop2905" /> + + + + + </linearGradient> + + + + + <linearGradient + id="linearGradient2862"> + <stop + offset="0.0000000" + style="stop-color:#bababa;stop-opacity:1.0000000;" + id="stop2863" /> + + + + + <stop + offset="1.00000000" + style="stop-color:#272727;stop-opacity:1;" + id="stop2864" /> + + + + + </linearGradient> + + + + + <linearGradient + id="linearGradient2859"> + <stop + offset="0.00000000" + style="stop-color:#ffffff;stop-opacity:1;" + id="stop2861" /> + + + + + <stop + offset="1.00000000" + style="stop-color:#545477;stop-opacity:1;" + id="stop2860" /> + + + + + </linearGradient> + + + + + <linearGradient + id="linearGradient2852" + gradientUnits="userSpaceOnUse" + x1="-9.1904" + y1="-14.3975" + x2="141.2382" + y2="162.8934"><stop + offset="0.00000000" + style="stop-color:#dddddd;stop-opacity:1;" + id="stop2854" /> + + + + +<stop + offset="1.00000000" + style="stop-color:#000000;stop-opacity:1;" + id="stop2856" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd21" + gradientUnits="userSpaceOnUse" + x1="-28.083" + y1="1.5566" + x2="122.4775" + y2="179.003"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop841" /> + + + + +<stop + offset="1" + style="stop-color:#8C8CA4" + id="stop843" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd22" + gradientUnits="userSpaceOnUse" + x1="40.3945" + y1="96.7637" + x2="89.7144" + y2="134.9468"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop850" /> + + + + +<stop + offset="1" + style="stop-color:#545477" + id="stop852" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd23" + gradientUnits="userSpaceOnUse" + x1="16.2939" + y1="53.1104" + x2="151.1777" + y2="213.9856"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop859" /> + + + + +<stop + offset="0.178" + style="stop-color:#FBFBFC" + id="stop861" /> + + + + +<stop + offset="0.367" + style="stop-color:#EEEEF2" + id="stop863" /> + + + + +<stop + offset="0.5612" + style="stop-color:#D9D9E1" + id="stop865" /> + + + + +<stop + offset="0.7589" + style="stop-color:#BBBBC9" + id="stop867" /> + + + + +<stop + offset="0.9575" + style="stop-color:#9595AB" + id="stop869" /> + + + + +<stop + offset="1" + style="stop-color:#8C8CA4" + id="stop871" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd24" + gradientUnits="userSpaceOnUse" + x1="-32.7295" + y1="5.502" + x2="117.8273" + y2="182.9439"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop878" /> + + + + +<stop + offset="1" + style="stop-color:#8C8CA4" + id="stop880" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd25" + gradientUnits="userSpaceOnUse" + x1="-17.4727" + y1="36.0361" + x2="33.1882" + y2="75.2575"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop887" /> + + + + +<stop + offset="1" + style="stop-color:#545477" + id="stop889" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd26" + gradientUnits="userSpaceOnUse" + x1="11.6523" + y1="57.0117" + x2="146.5186" + y2="217.8661"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop896" /> + + + + +<stop + offset="0.178" + style="stop-color:#FBFBFC" + id="stop898" /> + + + + +<stop + offset="0.367" + style="stop-color:#EEEEF2" + id="stop900" /> + + + + +<stop + offset="0.5612" + style="stop-color:#D9D9E1" + id="stop902" /> + + + + +<stop + offset="0.7589" + style="stop-color:#BBBBC9" + id="stop904" /> + + + + +<stop + offset="0.9575" + style="stop-color:#9595AB" + id="stop906" /> + + + + +<stop + offset="1" + style="stop-color:#8C8CA4" + id="stop908" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd27" + gradientUnits="userSpaceOnUse" + x1="-45.7183" + y1="16.5156" + x2="104.8478" + y2="193.9686"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop915" /> + + + + +<stop + offset="1" + style="stop-color:#8C8CA4" + id="stop917" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd28" + gradientUnits="userSpaceOnUse" + x1="4.2324" + y1="86.0156" + x2="46.406" + y2="118.6661"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop924" /> + + + + +<stop + offset="1" + style="stop-color:#545477" + id="stop926" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd29" + gradientUnits="userSpaceOnUse" + x1="-0.7148" + y1="67.3779" + x2="134.1636" + y2="228.2469"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop933" /> + + + + +<stop + offset="0.178" + style="stop-color:#FBFBFC" + id="stop935" /> + + + + +<stop + offset="0.367" + style="stop-color:#EEEEF2" + id="stop937" /> + + + + +<stop + offset="0.5612" + style="stop-color:#D9D9E1" + id="stop939" /> + + + + +<stop + offset="0.7589" + style="stop-color:#BBBBC9" + id="stop941" /> + + + + +<stop + offset="0.9575" + style="stop-color:#9595AB" + id="stop943" /> + + + + +<stop + offset="1" + style="stop-color:#8C8CA4" + id="stop945" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd30" + gradientUnits="userSpaceOnUse" + x1="4.0088" + y1="-25.6621" + x2="154.5634" + y2="151.7773"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop952" /> + + + + +<stop + offset="1" + style="stop-color:#8C8CA4" + id="stop954" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd31" + gradientUnits="userSpaceOnUse" + x1="89.7988" + y1="83.6094" + x2="132.9068" + y2="116.9833"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop961" /> + + + + +<stop + offset="1" + style="stop-color:#545477" + id="stop963" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd32" + gradientUnits="userSpaceOnUse" + x1="48.4219" + y1="26.1885" + x2="183.2913" + y2="187.0467"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop970" /> + + + + +<stop + offset="0.178" + style="stop-color:#FBFBFC" + id="stop972" /> + + + + +<stop + offset="0.367" + style="stop-color:#EEEEF2" + id="stop974" /> + + + + +<stop + offset="0.5612" + style="stop-color:#D9D9E1" + id="stop976" /> + + + + +<stop + offset="0.7589" + style="stop-color:#BBBBC9" + id="stop978" /> + + + + +<stop + offset="0.9575" + style="stop-color:#9595AB" + id="stop980" /> + + + + +<stop + offset="1" + style="stop-color:#8C8CA4" + id="stop982" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd33" + gradientUnits="userSpaceOnUse" + x1="-2.0176" + y1="-20.5537" + x2="148.5382" + y2="156.8871"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop989" /> + + + + +<stop + offset="1" + style="stop-color:#8C8CA4" + id="stop991" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd34" + gradientUnits="userSpaceOnUse" + x1="2.0205" + y1="-0.6567" + x2="45.127" + y2="32.716"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop998" /> + + + + +<stop + offset="1" + style="stop-color:#545477" + id="stop1000" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd35" + gradientUnits="userSpaceOnUse" + x1="42.2881" + y1="31.3262" + x2="177.1685" + y2="192.1976"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop1007" /> + + + + +<stop + offset="0.178" + style="stop-color:#FBFBFC" + id="stop1009" /> + + + + +<stop + offset="0.367" + style="stop-color:#EEEEF2" + id="stop1011" /> + + + + +<stop + offset="0.5612" + style="stop-color:#D9D9E1" + id="stop1013" /> + + + + +<stop + offset="0.7589" + style="stop-color:#BBBBC9" + id="stop1015" /> + + + + +<stop + offset="0.9575" + style="stop-color:#9595AB" + id="stop1017" /> + + + + +<stop + offset="1" + style="stop-color:#8C8CA4" + id="stop1019" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd36" + gradientUnits="userSpaceOnUse" + x1="-9.1904" + y1="-14.3975" + x2="141.2382" + y2="162.8934"><stop + offset="0.00000000" + style="stop-color:#e5e5e5;stop-opacity:1;" + id="stop1026" /> + + + + +<stop + offset="1.00000000" + style="stop-color:#5d5d5d;stop-opacity:1;" + id="stop1028" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd37" + gradientUnits="userSpaceOnUse" + x1="35.3623" + y1="37.1309" + x2="170.0874" + y2="197.817"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop1037" /> + + + + +<stop + offset="0.178" + style="stop-color:#FBFBFC" + id="stop1039" /> + + + + +<stop + offset="0.367" + style="stop-color:#EEEEF2" + id="stop1041" /> + + + + +<stop + offset="0.5612" + style="stop-color:#D9D9E1" + id="stop1043" /> + + + + +<stop + offset="0.7589" + style="stop-color:#BBBBC9" + id="stop1045" /> + + + + +<stop + offset="0.9575" + style="stop-color:#9595AB" + id="stop1047" /> + + + + +<stop + offset="1" + style="stop-color:#8C8CA4" + id="stop1049" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd38" + gradientUnits="userSpaceOnUse" + x1="-39.4014" + y1="-8.939" + x2="120.3301" + y2="114.7241"><stop + offset="0.0000000" + style="stop-color:#ffffff;stop-opacity:1.0000000;" + id="stop1056" /> + + + + +<stop + offset="1.0000000" + style="stop-color:#545477;stop-opacity:1.0000000;" + id="stop1058" /> + + + + +</linearGradient> + + + + + <linearGradient + id="aigrd39" + gradientUnits="userSpaceOnUse" + x1="-25.2842" + y1="-0.6992" + x2="115.9417" + y2="108.6369"><stop + offset="0" + style="stop-color:#FFFFFF" + id="stop1065" /> + + + + +<stop + offset="1" + style="stop-color:#545477" + id="stop1067" /> + + + + +</linearGradient> + + + + + <linearGradient + xlink:href="#linearGradient2862" + id="linearGradient2840" + x1="1.12130487" + y1="0.00000004" + x2="1.13968694" + y2="0.62938684" + gradientUnits="objectBoundingBox" + gradientTransform="scale(0.383105,2.610251)" /> + + + + + <linearGradient + xlink:href="#linearGradient2852" + id="linearGradient2841" + x1="0.58999997" + y1="1.43225801" + x2="0.58999997" + y2="-0.29032257" /> + + + + + <linearGradient + xlink:href="#aigrd36" + id="linearGradient2858" + x1="0.52366948" + y1="-0.42518446" + x2="0.51448232" + y2="1.13690627" + gradientTransform="scale(1.183122,0.845221)" /> + + + + + <linearGradient + xlink:href="#linearGradient2862" + id="linearGradient2883" + x1="0.61267602" + y1="1.11111093" + x2="0.51056337" + y2="-1.94444358" /> + + + + + <linearGradient + xlink:href="#linearGradient2862" + id="linearGradient2884" + x1="0.52366954" + y1="-0.42518461" + x2="0.51448244" + y2="1.13690686" + gradientUnits="objectBoundingBox" + gradientTransform="scale(1.183122,0.845221)" /> + + + + + <linearGradient + xlink:href="#linearGradient2862" + id="linearGradient2885" + x1="0.47535211" + y1="1.05555499" + x2="0.48239437" + y2="-0.83333248" /> + + + + + <linearGradient + xlink:href="#linearGradient2922" + id="linearGradient2901" + x1="0.45422533" + y1="1.27272785" + x2="0.45422533" + y2="-0.47727346" /> + + + + + <linearGradient + xlink:href="#linearGradient2922" + id="linearGradient2902" + x1="0.46478876" + y1="0.22727279" + x2="0.49647892" + y2="1.22727227" /> + + + + + <linearGradient + xlink:href="#aigrd36" + id="linearGradient2907" + x1="0.67000002" + y1="2.13548398" + x2="0.68000001" + y2="-0.32903227" /> + + + + + <linearGradient + xlink:href="#linearGradient2334" + id="linearGradient2919" + x1="0.52366930" + y1="-0.42518443" + x2="0.51448220" + y2="1.1369064" + gradientTransform="scale(1.183122,0.845221)" /> + + + + + <linearGradient + xlink:href="#linearGradient2925" + id="linearGradient2921" + x1="0.55633807" + y1="-0.40909052" + x2="0.37676060" + y2="1.50000036" /> + + + + + <linearGradient + xlink:href="#linearGradient2925" + id="linearGradient2929" + x1="0.40492961" + y1="1.29545498" + x2="0.41197187" + y2="-0.11363599" /> + + + + + <radialGradient + xlink:href="#linearGradient2925" + id="radialGradient2930" + cx="1.02941215" + cy="0.44531286" + r="0.81727701" + fx="1.05882394" + fy="0.44531289" /> + + + + + <linearGradient + xlink:href="#aigrd36" + id="linearGradient3127" + x1="0.52366924" + y1="-0.42518425" + x2="0.54469812" + y2="0.67493552" + gradientTransform="scale(1.183122,0.845221)" /> + + + + + <linearGradient + xlink:href="#linearGradient2334" + id="linearGradient3128" + x1="0.52366912" + y1="-0.42518413" + x2="0.54469800" + y2="0.67493540" + gradientTransform="scale(1.183122,0.845221)" /> + + + + + <linearGradient + xlink:href="#linearGradient2862" + id="linearGradient2983" + x1="0.50000000" + y1="0.80952382" + x2="0.16438356" + y2="-0.71428573" /> + +<linearGradient + xlink:href="#aigrd38" + id="linearGradient3009" + x1="0.32869712" + y1="0.73845887" + x2="0.35687116" + y2="0.56376964" + gradientTransform="scale(1.183122,0.845221)" + spreadMethod="reflect" /> + +<radialGradient + xlink:href="#linearGradient2334" + id="radialGradient3010" /> + +<linearGradient + xlink:href="#linearGradient2925" + id="linearGradient3614" + x1="0.68150687" + y1="0.62222224" + x2="0.65753424" + y2="0.62222224" + spreadMethod="reflect" /> + +<linearGradient + xlink:href="#linearGradient2925" + id="linearGradient3616" + x1="0.65753424" + y1="0.37777779" + x2="0.63356167" + y2="0.37777779" + spreadMethod="reflect" /> + +<linearGradient + xlink:href="#linearGradient2925" + id="linearGradient2669" + x1="0.52102673" + y1="-7.0396977e-16" + x2="0.51234299" + y2="1.4352630" + gradientTransform="scale(1.183122,0.845221)" /> +</defs> + +<sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="3.5265062" + inkscape:cx="94.402278" + inkscape:cy="41.604425" + inkscape:window-width="1214" + inkscape:window-height="947" + inkscape:window-x="0" + inkscape:window-y="0" + showgrid="false" /> + +<path + style="font-size:12;fill:none;stroke-width:0;" + d="M 115.9886 102.1745 L 33.68624 102.1745 L 33.68624 19.87214 L 115.9886 19.87214 L 115.9886 102.1745 z " + id="path578" /> + +<g + id="g3162" + transform="matrix(0.571544,0.000000,0.000000,0.571544,-49.93925,-69.61939)"> + <path + style="fill:url(#linearGradient2840);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M 6.8318508,152.48371 L 146.93881,146.61162 L 176.27474,140.97691 L 146.93881,135.47573 L 6.8318508,129.60364 L 6.8318508,152.48371 z " + id="path3145" + sodipodi:nodetypes="cccccc" + transform="matrix(0.443523,0.000000,0.000000,1.000000,20.30177,82.00000)" /> + + + + + <path + style="fill:url(#linearGradient2883);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M 11.171849,130.82818 L 11.642853,132.00569 L 23.535706,136.24473 L 24.285706,139.54175 L 166.85481,140.06153 L 146.58552,136.36248 L 11.171849,130.82818 z " + id="path3146" + sodipodi:nodetypes="ccccccc" + transform="matrix(0.443523,0.000000,0.000000,1.000000,20.30177,82.00000)" /> + + + + + <path + style="fill:url(#linearGradient2885);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M 10.421424,151.46914 L 12.838150,148.28275 L 38.133942,143.88838 L 37.961794,141.12168 L 169.19869,141.13223 L 146.96010,145.43484 L 10.421424,151.46914 z " + id="path3147" + sodipodi:nodetypes="ccccccc" + transform="matrix(0.443523,0.000000,0.000000,1.000000,20.30177,82.00000)" /> + + + + + <path + style="fill:#676767;fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M -20.006023,213.01026 C -20.700425,216.26127 -23.887613,217.12580 -24.210547,222.76330 C -23.686250,227.52198 -20.792988,229.09867 -20.144868,232.26635 C -15.504417,231.47346 -8.5143595,228.65759 0.87641127,228.78259 C 4.8387290,228.78259 16.497773,229.80036 20.000000,231.55036 L 19.686044,213.86013 C 15.261376,215.64272 6.4997101,216.71000 0.68005539,216.53323 C -11.881387,215.73145 -15.516122,214.26330 -20.006023,213.01026 z " + id="path3148" + sodipodi:nodetypes="cccccccc" /> + + + + + <path + style="fill:url(#linearGradient2929);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M -17.916064,222.20525 C -18.122435,216.34215 -18.947918,216.84302 -19.463845,214.16191 C -10.877000,216.36988 -5.5407115,217.53705 -0.071053296,217.60017 C 6.3950201,217.67361 14.690510,216.48947 17.311419,215.84128 L 16.506572,218.58132 L 16.568483,222.20524 C 5.0736346,222.20524 -6.4212148,222.20525 -17.916064,222.20525 z " + id="path3149" + sodipodi:nodetypes="ccscccc" /> + + + + + <path + style="fill:url(#linearGradient2921);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M -18.003620,223.28691 C -18.209991,229.15001 -19.035474,228.64914 -19.551401,231.33025 C -10.964556,229.12228 -5.6282671,227.95511 -0.15860898,227.89199 C 6.3074644,227.81855 14.602954,229.00269 17.223863,229.65088 L 16.419017,226.91084 L 16.480928,223.28692 C 4.9860789,223.28692 -6.5087705,223.28691 -18.003620,223.28691 z " + id="path3150" + sodipodi:nodetypes="ccscccc" /> + + + + + <path + style="fill:url(#radialGradient2930);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M -21.584549,222.27145 C -21.138223,218.26379 -20.444251,217.08456 -19.874103,214.49112 C -19.448413,217.24913 -18.651256,218.76971 -18.597034,222.76517 C -18.919539,226.62255 -19.489687,228.18183 -19.936014,230.89017 C -20.485526,228.01726 -21.220772,227.08890 -21.584549,222.27145 z " + id="path3151" + sodipodi:nodetypes="ccccc" /> + + + + + <path + style="fill:none;stroke-width:0.0000000;" + d="M 18.840672,207.82660 C 26.881957,215.62099 27.081497,228.45732 19.287681,236.49801 C 13.274566,242.70160 4.2611390,244.23279 -3.2369380,241.03179 C -3.4282240,241.34083 -3.6094850,241.63296 -3.7086950,241.79445 C 4.3248530,245.26436 13.758916,243.40673 19.865784,237.10642 C 27.982519,228.73258 27.773362,215.31720 19.398929,207.19988 C 13.135343,201.12861 3.6870220,199.54478 -4.2092660,203.20043 C -4.1159500,203.35862 -3.9413780,203.65579 -3.7562590,203.96955 C 3.6277490,200.57062 12.653806,201.82969 18.840374,207.82631 L 18.840672,207.82660 z " + id="path3152" /> + + + + + <g + id="g3153" + transform="translate(16.50000,82.00000)"> + <path + style="fill:url(#linearGradient2858);stroke:#0d0d0d;stroke-width:0.0000000;" + d="M 22.749298,137.26204 L 22.781812,143.87530 L 10.412035,148.27788 C 9.7678063,150.54765 8.4248173,153.44836 6.8963864,155.44805 L 9.2975563,163.23952 L 5.4261744,167.65155 L -3.0432268,165.18901 C -4.7281759,166.49119 -9.7925774,168.56358 -12.734554,169.14901 L -15.552495,177.14585 L -23.560420,179.37460 L -23.543496,162.45960 C -21.032305,162.38889 -18.219883,162.10785 -15.413465,161.44693 C -12.607047,160.78601 -9.7881700,159.77373 -7.3194595,158.15502 C -3.7274312,155.68095 -0.94416110,152.82671 0.92804030,147.45665 L -0.69267650,144.11107 L -0.83877690,137.42871 L 1.0981625,134.06659 C -1.8928284,127.25305 -2.3718214,126.32732 -7.1270936,122.86405 C -9.4688526,121.13298 -12.367410,120.31467 -15.186823,119.71643 C -18.006237,119.11820 -20.861923,118.90820 -23.464190,118.89821 L -23.481112,101.98321 L -15.473187,104.21197 L -12.655247,112.20880 C -9.7132691,112.79424 -4.6488675,114.86663 -2.9639184,116.16880 L 5.5054806,113.70626 L 9.3768623,118.11830 L 6.9756925,125.90977 C 8.5041233,127.90946 9.8471123,130.81017 10.491341,133.07993 L 22.749298,137.26204 z " + id="path3154" + sodipodi:nodetypes="cccccccccccssccccsscccccccccc" /> + + + + + <path + style="fill:url(#linearGradient2884);stroke:#0d0d0d;stroke-width:0.0000000;" + d="M 21.691342,138.06024 L 21.780828,143.20765 L 9.3970103,147.54423 C 8.4491973,150.60331 7.6577143,152.78047 5.5313886,155.22268 L 8.2190503,163.05720 L 5.2893156,166.52482 L -3.1846853,164.16622 C -4.8696344,165.46840 -10.620898,167.72298 -13.562874,168.30842 L -16.580987,176.62743 L -22.316859,178.03044 L -22.317719,163.80210 C -17.136716,163.59156 -2.3988463,161.97586 1.9920147,147.21901 L 0.34945910,143.87907 L 0.20938380,137.67953 L 2.0696939,134.35977 C -1.9662640,119.20324 -16.735537,117.68732 -22.150304,117.75940 L -22.271162,103.53329 L -16.210992,105.33272 L -13.668722,112.98608 C -10.726744,113.57152 -4.8534026,116.04918 -3.1684535,117.35135 L 5.2331486,114.89481 L 7.9476443,118.32617 L 5.5213236,125.97048 C 7.0497566,127.97017 8.7094363,130.80147 9.7891033,134.13288 L 21.691342,138.06024 z " + id="path3155" + sodipodi:nodetypes="ccccccccccccccccccccccccc" /> + + + + + <path + style="fill:none;fill-rule:evenodd;stroke:url(#linearGradient2841);stroke-width:0.60000002;" + d="M 3.0000000,134.75000 L 3.0000000,146.75000 L 5.7500000,147.31250 L 5.6875000,143.00000 L 8.6875003,146.43750 L 11.312500,145.62500 L 7.0625000,140.75000 L 11.375000,136.06250 L 8.8125003,135.00000 L 5.6875000,138.87500 L 5.7500000,134.12500 L 3.0000000,134.75000 z " + id="path3156" + sodipodi:nodetypes="cccccccccccc" /> + + + + + </g> + + + + + <path + style="fill:url(#radialGradient2930);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M -23.352316,222.27145 C -22.905990,218.26379 -20.444251,217.08456 -19.874103,214.49112 C -19.448413,217.24913 -18.651256,218.76971 -18.597034,222.76517 C -18.919539,226.62255 -19.489687,228.18183 -19.936014,230.89017 C -20.485526,228.01726 -22.988539,227.08890 -23.352316,222.27145 z " + id="path3157" + sodipodi:nodetypes="ccccc" /> + + + + + <path + style="fill:none;stroke-width:0.0000000;" + d="M 18.840672,207.82660 C 26.881957,215.62099 27.081497,228.45732 19.287681,236.49801 C 13.274566,242.70160 4.2611390,244.23279 -3.2369380,241.03179 C -3.4282240,241.34083 -3.6094850,241.63296 -3.7086950,241.79445 C 4.3248530,245.26436 13.758916,243.40673 19.865784,237.10642 C 27.982519,228.73258 27.773362,215.31720 19.398929,207.19988 C 13.135343,201.12861 3.6870220,199.54478 -4.2092660,203.20043 C -4.1159500,203.35862 -3.9413780,203.65579 -3.7562590,203.96955 C 3.6277490,200.57062 12.653806,201.82969 18.840374,207.82631 L 18.840672,207.82660 z " + id="path3158" /> + + + + + </g> + +<g + id="g3193" + transform="matrix(0.571544,0,0,0.571544,26.25755,17.95904)"> + <path + style="fill:#574005;fill-rule:evenodd;stroke:black;stroke-opacity:1;stroke-width:0.25;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;stroke-dasharray:none;" + d="M -25.115115 12.260255 C -26.106486 15.511271 -27.628186 16.375802 -28.089227 22.013303 C -27.340708 26.771976 -26.238635 28.348668 -25.313339 31.516351 C -18.688339 30.723458 7.291107 28.907594 12.947962 28.907594 C 18.604816 28.907594 27 29.050361 32 30.800361 L 31.551777 13.110128 C 25.234842 14.892724 20.601137 15.085003 12.292632 14.908226 C 3.984127 14.731449 -18.955049 12.5133 -25.115115 12.260255 z " + id="path2886" + sodipodi:nodetypes="cccccccc" /> + + + + + <path + style="font-size:12;fill:url(#linearGradient2840);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.198004;" + d="M 35.331851 33.733707 L 175.43881 27.861621 L 191.22323 22.226907 L 175.43881 16.725729 L 35.331851 10.853643 L 35.331851 33.733707 z " + id="path2880" + sodipodi:nodetypes="cccccc" /> + + + + + <path + style="font-size:12;fill:none;stroke-width:0;" + d="M 30.840672 7.076597 C 38.881957 14.870992 39.081497 27.707324 31.287681 35.748012 C 25.274566 41.951597 16.261139 43.482792 8.763062 40.281785 C 8.571776 40.590831 8.390515 40.882962 8.291305 41.044453 C 16.324853 44.514362 25.758916 42.656727 31.865784 36.356421 C 39.982519 27.982584 39.773362 14.5672 31.398929 6.449884 C 25.135343 0.37860796 15.687022 -1.20522 7.790734 2.450425 C 7.88405 2.60862 8.058622 2.905787 8.243741 3.219552 C 15.627749 -0.17937604 24.653806 1.079685 30.840374 7.076309 L 30.840672 7.076597 z " + id="path1033" /> + + + + + <path + style="font-size:12;fill:url(#linearGradient2858);stroke:#0d0d0d;stroke-width:0.282837;" + d="M 51.249298 18.51204 L 51.281812 25.125298 L 38.912035 29.527884 C 38.267806 31.797645 36.924817 34.698361 35.396386 36.698054 L 37.797556 44.489518 L 33.926174 48.901551 L 25.456773 46.439012 C 23.771824 47.74119 18.707423 49.813575 15.765446 50.399013 L 12.947505 58.395845 L 4.93958 60.624603 L 4.956504 43.709604 C 15.001269 43.426775 29.865729 39.778473 29.886827 21.914806 C 29.908662 3.428294 15.444876 0.18817096 5.03581 0.14821196 L 5.018888 -16.766788 L 13.026813 -14.538028 L 15.844753 -6.541198 C 18.786731 -5.95576 23.851133 -3.883374 25.536082 -2.581201 L 34.005481 -5.043738 L 37.876863 -0.63170504 L 35.475693 7.159766 C 37.004123 9.159456 38.347112 12.060173 38.991341 14.329934 L 51.249298 18.51204 z " + id="path2846" + sodipodi:nodetypes="cccccccccccccccccccccc" /> + + + + + <path + style="font-size:12;fill:url(#linearGradient2884);stroke:#0d0d0d;stroke-width:0.235696;" + d="M 50.235536 19.575406 L 50.280828 24.457649 L 37.89701 28.794226 C 36.949197 31.85331 36.157714 34.030473 34.031388 36.472684 L 36.719051 44.307202 L 33.789315 47.774821 L 25.315315 45.416217 C 23.630366 46.718395 17.879102 48.972979 14.937126 49.558417 L 11.919013 57.877429 L 6.183141 59.280443 L 6.182281 45.052097 C 11.363284 44.841563 26.101154 43.225858 30.492015 28.469007 L 28.849459 25.129073 L 28.709384 18.929533 L 30.569694 15.609773 C 26.533736 0.45324096 11.764463 -1.062681 6.349696 -0.99060404 L 6.228838 -15.216706 L 12.289008 -13.417281 L 14.831278 -5.763917 C 17.773256 -5.178481 23.646597 -2.70082 25.331547 -1.398646 L 33.733148 -3.855194 L 36.447645 -0.42383304 L 34.021323 7.220481 C 35.549756 9.220171 37.209437 12.051468 38.289103 15.382882 L 50.235536 19.575406 z " + id="path2851" + sodipodi:nodetypes="ccccccccccccccccccccccccc" /> + + + + + <path + style="fill:url(#linearGradient2883);fill-rule:evenodd;stroke:black;stroke-opacity:1;stroke-width:0.2;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;stroke-dasharray:none;" + d="M 39.671849 12.078179 L 40.142853 13.255689 L 52.035706 17.494726 L 52.785706 20.791754 L 185.78904 21.311532 L 175.08552 17.612477 L 39.671849 12.078179 z " + id="path2881" + sodipodi:nodetypes="ccccccc" /> + + + + + <path + style="fill:url(#linearGradient2885);fill-rule:evenodd;stroke:#000000;stroke-opacity:1;stroke-width:0.2;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;stroke-dasharray:none;" + d="M 38.921424 32.719136 L 40.142428 30.416626 L 52.285281 26.552589 L 52.910281 23.255561 L 186.53862 22.735783 L 175.4601 26.684838 L 38.921424 32.719136 z " + id="path2882" + sodipodi:nodetypes="ccccccc" /> + + + + + <path + style="fill:url(#linearGradient2902);fill-rule:evenodd;stroke:black;stroke-opacity:1;stroke-width:0.25;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;stroke-dasharray:none;" + d="M -22.131358 21.455245 C -22.425986 15.592151 -23.604497 16.093018 -24.341067 13.411905 C -10.581947 14.619879 1.668407 15.535267 15.345302 15.975167 C 21.82095 16.183448 24.419838 15.739465 28.161612 15.091284 L 27.012563 17.831322 L 27.100952 21.455244 C 10.690182 21.455244 -5.720588 21.455245 -22.131358 21.455245 z " + id="path2887" + sodipodi:nodetypes="ccscccc" /> + + + + + <path + style="fill:url(#linearGradient2901);fill-rule:evenodd;stroke:black;stroke-opacity:1;stroke-width:0.25;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;stroke-dasharray:none;" + d="M -22.219746 22.604292 C -22.514374 28.467386 -23.692885 27.966519 -24.429455 30.647632 C -10.670335 29.439658 1.580019 28.52427 15.256914 28.08437 C 21.732561 27.876089 24.33145 28.320072 28.073223 28.968253 L 26.924175 26.228215 L 27.012563 22.604293 C 10.601794 22.604293 -5.808976 22.604292 -22.219746 22.604292 z " + id="path2899" + sodipodi:nodetypes="ccscccc" /> + + + + + <path + style="fill:none;fill-rule:evenodd;stroke:black;stroke-opacity:1;stroke-width:0.25;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:0.75;stroke-dasharray:none;" + d="M -25.136562 12.528021 L -24.69462 15.356448 L -23.987514 18.361652 L -23.280406 21.808797 L -23.899125 25.344332 L -24.429455 27.995982 L -25.22495 31.531516 L -25.136562 31.619904 " + id="path2900" + sodipodi:nodetypes="cccccccc" /> + + + + + <path + style="fill:#454545;fill-rule:evenodd;stroke:url(#linearGradient2907);stroke-opacity:1;stroke-width:0.2;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;stroke-dasharray:none;" + d="M 31.5 16 L 31.5 28 L 34.25 28.5625 L 34.1875 24.25 L 37.1875 27.6875 L 39.8125 26.875 L 35.5625 22 L 39.875 17.3125 L 37.3125 16.25 L 34.1875 20.125 L 34.25 15.375 L 31.5 16 z " + id="path2906" + sodipodi:nodetypes="cccccccccccc" /> + + + + + </g> + + + <path + style="font-size:12.000000;fill:url(#linearGradient2840);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M 6.8318508 152.48371 L 146.93881 146.61162 L 162.72323 140.97691 L 146.93881 135.47573 L 6.8318508 129.60364 L 6.8318508 152.48371 z " + id="path2909" + sodipodi:nodetypes="cccccc" + transform="matrix(0.571544,0.000000,0.000000,0.571544,39.94149,0.822029)" /> + + + + + <path + style="fill:url(#linearGradient2883);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M 11.171849,130.82818 L 11.642853,132.00569 L 23.535706,136.24473 L 24.285706,139.54175 L 158.86775,140.58777 L 146.58552,136.36248 L 11.171849,130.82818 z " + id="path2913" + sodipodi:nodetypes="ccccccc" + transform="matrix(0.571544,0.000000,0.000000,0.571544,39.94149,0.822029)" /> + + + + + <path + style="fill:url(#linearGradient2983);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M 10.421424,151.46914 L 11.642428,149.16663 L 23.785281,145.30259 L 24.410281,142.00556 L 159.44192,140.95954 L 146.96010,145.43484 L 10.421424,151.46914 z " + id="path2914" + sodipodi:nodetypes="ccccccc" + transform="matrix(0.571544,0.000000,0.000000,0.571544,39.94149,0.822029)" /> + + + + + <path + style="font-size:12.000000;fill:#676767;fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M -68.365115 126.01026 C -69.356486 129.26127 -70.878186 130.1258 -71.339227 135.7633 C -70.590708 140.52198 -69.488635 142.09867 -68.563339 145.26635 C -61.938339 144.47346 -51.958893 141.65759 -38.552038 141.78259 C -32.895184 141.78259 -16.25 142.80036 -11.25 144.55036 L -11.698223 126.86013 C -18.015158 128.64272 -30.523863 129.71 -38.832368 129.53323 C -56.765873 128.73145 -61.955049 127.2633 -68.365115 126.01026 z " + id="path2908" + sodipodi:nodetypes="cccccccc" + transform="matrix(0.571544,0.000000,0.000000,0.571544,48.37176,3.679749)" /> + +<path + style="font-size:12.000000;fill:url(#linearGradient2929);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M -65.381358 135.20525 C -65.675986 129.34215 -66.854497 129.84302 -67.591067 127.16191 C -55.331947 129.36988 -47.713526 130.53705 -39.904698 130.60017 C -30.673325 130.67361 -18.830162 129.48947 -15.088388 128.84128 L -16.237437 131.58132 L -16.149049 135.20524 C -32.559818 135.20524 -48.970588 135.20525 -65.381358 135.20525 z " + id="path2915" + sodipodi:nodetypes="ccscccc" + transform="matrix(0.571544,0.000000,0.000000,0.571544,48.37176,3.679749)" /> + +<path + style="font-size:12.000000;fill:url(#linearGradient2921);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M -65.506358 136.28691 C -65.800986 142.15001 -66.979497 141.64914 -67.716067 144.33025 C -55.456947 142.12228 -47.838526 140.95511 -40.029698 140.89199 C -30.798325 140.81855 -18.955162 142.00269 -15.213388 142.65088 L -16.362437 139.91084 L -16.274049 136.28692 C -32.684818 136.28692 -49.095588 136.28691 -65.506358 136.28691 z " + id="path2920" + sodipodi:nodetypes="ccscccc" + transform="matrix(0.571544,0.000000,0.000000,0.571544,48.37176,3.679749)" /> + +<path + style="font-size:12.000000;fill:url(#radialGradient2930);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M -70.618718 135.27145 C -69.981515 131.26379 -68.990757 130.08456 -68.176777 127.49112 C -67.569036 130.24913 -66.430964 131.76971 -66.353553 135.76517 C -66.813981 139.62255 -67.627961 141.18183 -68.265165 143.89017 C -69.049683 141.01726 -70.099366 140.0889 -70.618718 135.27145 z " + id="path2928" + sodipodi:nodetypes="ccccc" + transform="matrix(0.571544,0.000000,0.000000,0.571544,48.37176,3.679749)" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<path + style="fill:url(#linearGradient3127);stroke:#0d0d0d;stroke-width:0.0000000;" + d="M -54.452098,42.652777 L -54.420848,52.309027 C -52.933534,52.314737 -51.313518,52.435862 -49.702098,52.777777 C -48.090680,53.119697 -46.446766,53.569645 -45.108348,54.559027 C -42.390502,56.538438 -42.099081,57.071040 -40.389598,60.965277 L -41.514598,62.902777 L -41.420848,66.715277 L -40.483348,68.621527 C -41.553394,71.690753 -43.149096,73.332485 -45.202098,74.746527 C -46.613075,75.671691 -48.223105,76.243781 -49.827098,76.621527 C -51.431090,76.999272 -53.048092,77.174866 -54.483348,77.215277 L -54.483348,86.871527 L -49.920848,85.590277 L -48.295848,81.027777 C -46.614380,80.693178 -43.727621,79.522028 -42.764598,78.777777 L -37.920848,80.184027 L -35.702098,77.652777 L -37.077098,73.184027 C -36.203534,72.041116 -35.445303,70.387553 -35.077098,69.090277 L -28.014598,66.590277 L -28.014598,62.809027 L -35.014598,60.402777 C -35.382804,59.105509 -36.172283,57.451936 -37.045848,56.309027 L -35.670848,51.871527 L -37.889598,49.340277 L -42.702098,50.746527 C -43.665122,50.002280 -46.583129,48.831131 -48.264598,48.496527 L -49.858348,43.902777 L -54.452098,42.652777 z " + id="path2344" + transform="translate(81.30761,16.54224)" /> + +<path + sodipodi:type="inkscape:offset" + inkscape:radius="-0.56522751" + inkscape:original="M -54.437500 42.656250 L -54.406250 52.312500 C -52.918935 52.318208 -51.298920 52.439335 -49.687500 52.781250 C -48.076081 53.123168 -46.432168 53.573118 -45.093750 54.562500 C -42.375903 56.541909 -42.084483 57.074513 -40.375000 60.968750 L -41.500000 62.906250 L -41.406250 66.718750 L -40.468750 68.625000 C -41.538795 71.694224 -43.134498 73.335958 -45.187500 74.750000 C -46.598476 75.675162 -48.208507 76.247254 -49.812500 76.625000 C -51.416491 77.002743 -53.033494 77.178339 -54.468750 77.218750 L -54.468750 86.875000 L -49.906250 85.593750 L -48.281250 81.031250 C -46.599781 80.696649 -43.713023 79.525501 -42.750000 78.781250 L -37.906250 80.187500 L -35.687500 77.656250 L -37.062500 73.187500 C -36.188935 72.044587 -35.430705 70.391026 -35.062500 69.093750 L -28.000000 66.593750 L -28.000000 62.812500 L -35.000000 60.406250 C -35.368205 59.108980 -36.157685 57.455409 -37.031250 56.312500 L -35.656250 51.875000 L -37.875000 49.343750 L -42.687500 50.750000 C -43.650523 50.005751 -46.568531 48.834604 -48.250000 48.500000 L -49.843750 43.906250 L -54.437500 42.656250 z " + inkscape:href="path2344" + style="fill:url(#linearGradient3128);stroke:#0d0d0d;stroke-width:0.0000000;" + id="path2353" + d="M -53.875000,43.375000 L -53.843750,51.812500 C -52.476357,51.843063 -51.029592,51.907459 -49.562500,52.218750 C -47.928943,52.565365 -46.200452,53.021551 -44.750000,54.093750 C -42.008693,56.090245 -41.555112,56.851483 -39.843750,60.750000 C -39.775713,60.912435 -39.787267,61.097300 -39.875000,61.250000 L -40.937500,63.062500 L -40.843750,66.593750 L -39.968750,68.375000 C -39.899874,68.510684 -39.888609,68.668405 -39.937500,68.812500 C -41.044423,71.987502 -42.766363,73.766388 -44.875000,75.218750 C -46.361506,76.193436 -48.041709,76.799911 -49.687500,77.187500 C -51.151751,77.532334 -52.566867,77.653888 -53.906250,77.718750 L -53.906250,86.156250 L -50.343750,85.156250 L -48.812500,80.843750 C -48.751619,80.656539 -48.597726,80.514484 -48.406250,80.468750 C -47.628593,80.314001 -46.496029,79.948745 -45.468750,79.531250 C -44.441471,79.113755 -43.472547,78.636495 -43.093750,78.343750 C -42.951355,78.235035 -42.765856,78.200254 -42.593750,78.250000 L -38.125000,79.562500 L -36.312500,77.500000 L -37.593750,73.343750 C -37.643496,73.171644 -37.608715,72.986145 -37.500000,72.843750 C -36.690339,71.784444 -35.940750,70.160067 -35.593750,68.937500 C -35.545063,68.765091 -35.417533,68.625967 -35.250000,68.562500 L -28.562500,66.187500 L -28.562500,63.218750 L -35.187500,60.937500 C -35.355033,60.874033 -35.482563,60.734909 -35.531250,60.562500 C -35.875957,59.348020 -36.655141,57.720717 -37.468750,56.656250 C -37.577465,56.513855 -37.612246,56.328356 -37.562500,56.156250 L -36.281250,52.031250 L -38.093750,49.968750 L -42.531250,51.281250 C -42.703356,51.330996 -42.888855,51.296215 -43.031250,51.187500 C -43.407706,50.896565 -44.370975,50.417643 -45.406250,50.000000 C -46.441525,49.582357 -47.596685,49.217381 -48.375000,49.062500 C -48.566476,49.016766 -48.720369,48.874711 -48.781250,48.687500 L -50.281250,44.375000 L -53.875000,43.375000 z " + transform="translate(81.30760,16.56767)" /> + +<path + style="font-size:12.000000;fill:none;stroke-width:0.0000000;" + d="M -12.409328 120.8266 C -4.368043 128.62099 -4.168503 141.45732 -11.962319 149.49801 C -17.975434 155.7016 -26.988861 157.23279 -34.486938 154.03179 C -34.678224 154.34083 -34.859485 154.63296 -34.958695 154.79445 C -26.925147 158.26436 -17.491084 156.40673 -11.384216 150.10642 C -3.267481 141.73258 -3.476638 128.3172 -11.851071 120.19988 C -18.114657 114.12861 -27.562978 112.54478 -35.459266 116.20043 C -35.36595 116.35862 -35.191378 116.65579 -35.006259 116.96955 C -27.622251 113.57062 -18.596194 114.82969 -12.409626 120.82631 L -12.409328 120.8266 z " + id="path2910" + transform="matrix(0.571544,0.000000,0.000000,0.571544,48.37176,3.679749)" /> + +<path + style="fill:url(#linearGradient3127);stroke:#0d0d0d;stroke-width:0.0000000;" + d="M 164.06690,27.804225 L 164.08548,31.583994 L 157.01561,34.100262 C 156.64740,35.397535 155.87983,37.055419 155.00626,38.198329 L 156.37863,42.651497 L 154.16597,45.173167 L 149.32533,43.765717 C 148.36231,44.509970 145.46778,45.694432 143.78631,46.029031 L 142.17574,50.599577 L 137.59886,51.873406 L 137.60853,42.205739 C 139.04378,42.165325 140.65121,42.004698 142.25520,41.626953 C 143.85919,41.249208 145.47030,40.670646 146.88128,39.745482 C 148.93428,38.331442 150.52504,36.700118 151.59509,33.630893 L 150.66878,31.718747 L 150.58527,27.899484 L 151.69232,25.977884 C 149.98284,22.083646 149.70907,21.554551 146.99122,19.575140 C 145.65281,18.585757 143.99615,18.118057 142.38473,17.776136 C 140.77332,17.434222 139.14117,17.314197 137.65386,17.308488 L 137.64418,7.6408212 L 142.22107,8.9146552 L 143.83164,13.485196 C 145.51311,13.819800 148.40764,15.004262 149.37066,15.748510 L 154.21130,14.341060 L 156.42396,16.862735 L 155.05159,21.315903 C 155.92515,22.458814 156.69273,24.116697 157.06094,25.413965 L 164.06690,27.804225 z " + id="path2911" + sodipodi:nodetypes="cccccccccccssccccsscccccccccc" /> + +<path + style="fill:url(#linearGradient2919);stroke:#0d0d0d;stroke-width:0.0000000;" + d="M 163.46223,28.260431 L 163.51337,31.202402 L 156.43548,33.680948 C 155.89376,35.429347 155.44139,36.673690 154.22610,38.069520 L 155.76222,42.547293 L 154.08775,44.529191 L 149.24448,43.181147 C 148.28146,43.925400 144.99436,45.213992 143.31289,45.548597 L 141.58791,50.303280 L 138.30961,51.105160 L 138.30911,42.973036 C 141.27028,42.852704 149.69363,41.929260 152.20320,33.495071 L 151.26440,31.586148 L 151.18434,28.042838 L 152.24759,26.145449 C 149.94087,17.482826 141.49958,16.616411 138.40480,16.657608 L 138.33572,8.5267602 L 141.79938,9.5552132 L 143.25240,13.929445 C 144.93387,14.264050 148.29074,15.680142 149.25376,16.424389 L 154.05565,15.020368 L 155.60710,16.981542 L 154.22035,21.350601 C 155.09392,22.493512 156.04250,24.111724 156.65958,26.015772 L 163.46223,28.260431 z " + id="path2912" + sodipodi:nodetypes="ccccccccccccccccccccccccc" /> + +<path + style="fill:none;fill-rule:evenodd;stroke:url(#linearGradient2841);stroke-width:0.34292641;" + d="M 41.856634,77.837583 L 41.856634,84.696111 L 43.428380,85.017605 L 43.392658,82.552821 L 45.107291,84.517504 L 46.607593,84.053124 L 44.178531,81.266847 L 46.643315,78.587735 L 45.178734,77.980469 L 43.392658,80.195202 L 43.428380,77.480368 L 41.856634,77.837583 z " + id="path2918" + sodipodi:nodetypes="cccccccccccc" /> + +<path + style="font-size:12.000000;fill:url(#radialGradient2930);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + d="M -70.618718 135.27145 C -69.981515 131.26379 -68.990757 130.08456 -68.176777 127.49112 C -67.569036 130.24913 -66.430964 131.76971 -66.353553 135.76517 C -66.813981 139.62255 -67.627961 141.18183 -68.265165 143.89017 C -69.049683 141.01726 -70.099366 140.0889 -70.618718 135.27145 z " + id="path3012" + sodipodi:nodetypes="ccccc" + transform="matrix(0.571544,0.000000,0.000000,0.571544,48.37176,3.679749)" /> + +<path + style="font-size:12.000000;fill:none;stroke-width:0.0000000;" + d="M -12.409328 120.8266 C -4.368043 128.62099 -4.168503 141.45732 -11.962319 149.49801 C -17.975434 155.7016 -26.988861 157.23279 -34.486938 154.03179 C -34.678224 154.34083 -34.859485 154.63296 -34.958695 154.79445 C -26.925147 158.26436 -17.491084 156.40673 -11.384216 150.10642 C -3.267481 141.73258 -3.476638 128.3172 -11.851071 120.19988 C -18.114657 114.12861 -27.562978 112.54478 -35.459266 116.20043 C -35.36595 116.35862 -35.191378 116.65579 -35.006259 116.96955 C -27.622251 113.57062 -18.596194 114.82969 -12.409626 120.82631 L -12.409328 120.8266 z " + id="path3013" + transform="matrix(0.571544,0.000000,0.000000,0.571544,48.37176,3.679749)" /> + +<path + sodipodi:type="inkscape:offset" + inkscape:radius="-0.56522751" + inkscape:original="M -54.437500 42.656250 L -54.406250 52.312500 C -52.918935 52.318208 -51.298920 52.439335 -49.687500 52.781250 C -48.076081 53.123168 -46.432168 53.573118 -45.093750 54.562500 C -42.375903 56.541909 -42.084483 57.074513 -40.375000 60.968750 L -41.500000 62.906250 L -41.406250 66.718750 L -40.468750 68.625000 C -41.538795 71.694224 -43.134498 73.335958 -45.187500 74.750000 C -46.598476 75.675162 -48.208507 76.247254 -49.812500 76.625000 C -51.416491 77.002743 -53.033494 77.178339 -54.468750 77.218750 L -54.468750 86.875000 L -49.906250 85.593750 L -48.281250 81.031250 C -46.599781 80.696649 -43.713023 79.525501 -42.750000 78.781250 L -37.906250 80.187500 L -35.687500 77.656250 L -37.062500 73.187500 C -36.188935 72.044587 -35.430705 70.391026 -35.062500 69.093750 L -28.000000 66.593750 L -28.000000 62.812500 L -35.000000 60.406250 C -35.368205 59.108980 -36.157685 57.455409 -37.031250 56.312500 L -35.656250 51.875000 L -37.875000 49.343750 L -42.687500 50.750000 C -43.650523 50.005751 -46.568531 48.834604 -48.250000 48.500000 L -49.843750 43.906250 L -54.437500 42.656250 z " + inkscape:href="path2344" + style="fill:url(#linearGradient3009);stroke:#0d0d0d;stroke-width:0.0000000;opacity:0.17297297;" + id="path3014" + d="M -53.875000,43.375000 L -53.843750,51.812500 C -52.476357,51.843063 -51.029592,51.907459 -49.562500,52.218750 C -47.928943,52.565365 -46.200452,53.021551 -44.750000,54.093750 C -42.008693,56.090245 -41.555112,56.851483 -39.843750,60.750000 C -39.775713,60.912435 -39.787267,61.097300 -39.875000,61.250000 L -40.937500,63.062500 L -40.843750,66.593750 L -39.968750,68.375000 C -39.899874,68.510684 -39.888609,68.668405 -39.937500,68.812500 C -41.044423,71.987502 -42.766363,73.766388 -44.875000,75.218750 C -46.361506,76.193436 -48.041709,76.799911 -49.687500,77.187500 C -51.151751,77.532334 -52.566867,77.653888 -53.906250,77.718750 L -53.906250,86.156250 L -50.343750,85.156250 L -48.812500,80.843750 C -48.751619,80.656539 -48.597726,80.514484 -48.406250,80.468750 C -47.628593,80.314001 -46.496029,79.948745 -45.468750,79.531250 C -44.441471,79.113755 -43.472547,78.636495 -43.093750,78.343750 C -42.951355,78.235035 -42.765856,78.200254 -42.593750,78.250000 L -38.125000,79.562500 L -36.312500,77.500000 L -37.593750,73.343750 C -37.643496,73.171644 -37.608715,72.986145 -37.500000,72.843750 C -36.690339,71.784444 -35.940750,70.160067 -35.593750,68.937500 C -35.545063,68.765091 -35.417533,68.625967 -35.250000,68.562500 L -28.562500,66.187500 L -28.562500,63.218750 L -35.187500,60.937500 C -35.355033,60.874033 -35.482563,60.734909 -35.531250,60.562500 C -35.875957,59.348020 -36.655141,57.720717 -37.468750,56.656250 C -37.577465,56.513855 -37.612246,56.328356 -37.562500,56.156250 L -36.281250,52.031250 L -38.093750,49.968750 L -42.531250,51.281250 C -42.703356,51.330996 -42.888855,51.296215 -43.031250,51.187500 C -43.407706,50.896565 -44.370975,50.417643 -45.406250,50.000000 C -46.441525,49.582357 -47.596685,49.217381 -48.375000,49.062500 C -48.566476,49.016766 -48.720369,48.874711 -48.781250,48.687500 L -50.281250,44.375000 L -53.875000,43.375000 z " + transform="translate(81.31000,16.42433)" /> + +<path + style="font-size:12.000000;fill:url(#linearGradient3614);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;opacity:0.24864865;" + d="M -65.381358 135.20525 C -65.675986 129.34215 -66.854497 129.84302 -67.591067 127.16191 C -55.331947 129.36988 -47.713526 130.53705 -39.904698 130.60017 C -30.673325 130.67361 -18.830162 129.48947 -15.088388 128.84128 L -16.237437 131.58132 L -16.149049 135.20524 C -32.559818 135.20524 -48.970588 135.20525 -65.381358 135.20525 z " + id="path3613" + sodipodi:nodetypes="ccscccc" + transform="matrix(0.571544,0.000000,0.000000,0.571544,48.37176,3.679749)" /> + +<path + style="font-size:12.000000;fill:url(#linearGradient3616);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;opacity:0.20000000;" + d="M -65.506358 136.28691 C -65.800986 142.15001 -66.979497 141.64914 -67.716067 144.33025 C -55.456947 142.12228 -47.838526 140.95511 -40.029698 140.89199 C -30.798325 140.81855 -18.955162 142.00269 -15.213388 142.65088 L -16.362437 139.91084 L -16.274049 136.28692 C -32.684818 136.28692 -49.095588 136.28691 -65.506358 136.28691 z " + id="path3615" + sodipodi:nodetypes="ccscccc" + transform="matrix(0.571544,0.000000,0.000000,0.571544,48.37176,3.679749)" /> + +<rect + width="169.56570" + height="84.472229" + ry="4.0219078" + x="-22.965296" + y="112.53943" + style="font-size:12.000000;fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:0.50800002;" + id="rect1068" + rx="4.0219078" /> + + + + + + + + + + + + + + + + + + <text + id="text854" + transform="scale(0.924295,0.924295)" + x="-151.74109" + y="59.269714" /> + + <rect + width="68.223778" + height="13.633065" + rx="5.3597374" + ry="3.9103417" + x="72.792801" + y="105.70743" + style="fill:url(#linearGradient2669);fill-rule:evenodd;stroke:#000000;stroke-width:0.25227949;" + id="rect1066" /> + + <text + id="text856" + transform="scale(0.924295,0.924295)" + x="-151.74109" + y="59.269714" /> + + <g + transform="matrix(0.289581,0.000000,0.000000,0.289581,137.2812,183.9399)" + id="g1103"> + <text + id="text858" /> + + <text + x="-211.79260" + y="-269.36719" + style="font-size:36.000000;fill:#9d9d9d;font-family:PostAntiqua;" + id="text1074"> + <tspan + x="-211.79260" + y="-233.36720" + id="tspan1083">KIO-SWORD</tspan> + </text> + + <text + id="text864" /> + + <text + x="-209.93480" + y="-270.89661" + style="font-size:36.000000;font-family:PostAntiqua;" + id="text1094"> + <tspan + x="-209.93480" + y="-234.89661" + id="tspan1095">KIO-SWORD</tspan> + </text> + + <text + id="text870" /> + + </g> + + <text + id="text871" + transform="scale(0.924295,0.924295)" + x="-151.74109" + y="59.269714" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + <g + transform="translate(79.08239,-108.1777)" + style="font-size:12.000000;" + id="g1653"> + <text + id="text880" /> + + <path + d="M 82.098340,196.82230 L 109.00400,194.67480 L 113.94060,192.37500 L 108.11510,190.12580 L 82.098340,188.13990 L 82.098340,196.82230 z " + transform="matrix(0.718454,-0.695575,0.695575,0.718454,-94.57463,111.3119)" + style="fill:url(#linearGradient2840);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + id="path974" /> + + <text + id="text882" /> + + <path + d="M 82.966820,188.60460 L 83.061070,189.05150 L 85.440980,190.66010 L 85.591060,191.91120 L 112.20660,192.10840 L 107.64030,190.62390 L 82.966820,188.60460 z " + transform="matrix(0.718454,-0.695575,0.695575,0.718454,-94.57463,111.3119)" + style="fill:url(#linearGradient2883);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + id="path976" /> + + <text + id="text884" /> + + <path + d="M 82.816650,196.43730 L 83.061000,195.56360 L 85.490920,194.09730 L 85.615990,192.84610 L 112.59900,192.56810 L 108.92750,194.14750 L 82.816650,196.43730 z " + transform="matrix(0.718454,-0.695575,0.695575,0.718454,-94.57463,111.3119)" + style="fill:url(#linearGradient2885);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + id="path978" /> + + <text + id="text886" /> + + <path + d="M 59.160260,188.67370 C 58.784060,189.90740 58.206620,190.23550 58.031670,192.37470 C 58.315710,194.18050 58.733920,194.77890 59.085040,195.98090 C 61.599060,195.68000 65.386000,194.61150 70.473550,194.65890 C 72.620180,194.65890 78.936600,195.04510 80.833970,195.70920 L 80.663880,188.99620 C 78.266770,189.67270 73.520040,190.07770 70.367170,190.01060 C 63.561870,189.70630 61.592720,189.14920 59.160260,188.67370 z " + transform="matrix(0.718454,-0.695575,0.695575,0.718454,-94.57463,111.3119)" + style="fill:#676767;fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + id="path981" /> + + <text + id="text888" /> + + <path + d="M 60.292520,192.16300 C 60.180720,189.93810 59.733500,190.12820 59.453990,189.11070 C 64.106010,189.94860 66.997010,190.39150 69.960250,190.41550 C 73.463320,190.44330 77.957490,189.99400 79.377400,189.74800 L 78.941360,190.78780 L 78.974910,192.16300 C 72.747440,192.16300 66.519980,192.16300 60.292520,192.16300 z " + transform="matrix(0.718454,-0.695575,0.695575,0.718454,-94.57463,111.3119)" + style="fill:url(#linearGradient2929);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + id="path983" /> + + <text + id="text890" /> + + <path + d="M 60.245090,192.57340 C 60.133280,194.79830 59.686070,194.60830 59.406560,195.62570 C 64.058580,194.78780 66.949570,194.34490 69.912820,194.32090 C 73.415890,194.29310 77.910060,194.74240 79.329960,194.98840 L 78.893930,193.94860 L 78.927470,192.57340 C 72.700010,192.57340 66.472550,192.57340 60.245090,192.57340 z " + transform="matrix(0.718454,-0.695575,0.695575,0.718454,-94.57463,111.3119)" + style="fill:url(#linearGradient2921);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + id="path985" /> + + <text + id="text892" /> + + <path + d="M 58.305080,192.18810 C 58.546880,190.66730 58.922850,190.21980 59.231730,189.23570 C 59.462350,190.28230 59.894220,190.85930 59.923600,192.37550 C 59.748880,193.83920 59.439990,194.43090 59.198190,195.45870 C 58.900490,194.36850 58.502160,194.01620 58.305080,192.18810 z " + transform="matrix(0.718454,-0.695575,0.695575,0.718454,-94.57463,111.3119)" + style="fill:url(#radialGradient2930);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + id="path987" /> + + <text + id="text894" /> + + <path + d="M 80.394030,186.70670 C 83.445490,189.66440 83.521210,194.53550 80.563660,197.58670 C 78.281840,199.94080 74.861480,200.52190 72.016150,199.30720 C 71.943560,199.42440 71.874780,199.53530 71.837130,199.59660 C 74.885660,200.91330 78.465640,200.20840 80.783040,197.81760 C 83.863130,194.63990 83.783760,189.54910 80.605880,186.46880 C 78.229010,184.16490 74.643620,183.56390 71.647180,184.95110 C 71.682590,185.01120 71.748840,185.12390 71.819080,185.24300 C 74.621120,183.95320 78.046280,184.43100 80.393920,186.70650 L 80.394030,186.70670 z " + transform="matrix(0.718454,-0.695575,0.695575,0.718454,-94.57463,111.3119)" + style="fill:none;stroke-width:0.0000000;" + id="path989" /> + + <text + id="text896" /> + + <g + transform="matrix(0.272635,-0.263953,0.263953,0.272635,59.20284,155.8451)" + id="g991"> + <text + id="text898" /> + + <path + d="M 22.749300,137.26200 L 22.781810,143.87530 L 10.412030,148.27790 C 9.7678060,150.54770 8.4248170,153.44840 6.8963860,155.44800 L 9.2975560,163.23950 L 5.4261740,167.65150 L -3.0432270,165.18900 C -4.7281760,166.49120 -9.7925770,168.56360 -12.734550,169.14900 L -15.552500,177.14580 L -23.560420,179.37460 L -23.543500,162.45960 C -21.032310,162.38890 -18.219880,162.10790 -15.413470,161.44690 C -12.607050,160.78600 -9.7881700,159.77370 -7.3194590,158.15500 C -3.7274310,155.68090 -0.94416100,152.82670 0.92804000,147.45660 L -0.69267600,144.11110 L -0.83877700,137.42870 L 1.0981620,134.06660 C -1.8928280,127.25310 -2.3718210,126.32730 -7.1270940,122.86410 C -9.4688530,121.13300 -12.367410,120.31470 -15.186820,119.71640 C -18.006240,119.11820 -20.861920,118.90820 -23.464190,118.89820 L -23.481110,101.98320 L -15.473190,104.21200 L -12.655250,112.20880 C -9.7132690,112.79420 -4.6488670,114.86660 -2.9639180,116.16880 L 5.5054810,113.70630 L 9.3768620,118.11830 L 6.9756930,125.90980 C 8.5041230,127.90950 9.8471120,130.81020 10.491340,133.07990 L 22.749300,137.26200 z " + style="fill:url(#linearGradient2858);stroke:#0d0d0d;stroke-width:0.0000000;" + id="path993" /> + + <text + id="text900" /> + + <path + d="M 21.691340,138.06020 L 21.780830,143.20770 L 9.3970100,147.54420 C 8.4491970,150.60330 7.6577140,152.78050 5.5313890,155.22270 L 8.2190500,163.05720 L 5.2893160,166.52480 L -3.1846850,164.16620 C -4.8696340,165.46840 -10.620900,167.72300 -13.562870,168.30840 L -16.580990,176.62740 L -22.316860,178.03040 L -22.317720,163.80210 C -17.136720,163.59160 -2.3988460,161.97590 1.9920150,147.21900 L 0.34945900,143.87910 L 0.20938400,137.67950 L 2.0696940,134.35980 C -1.9662640,119.20320 -16.735540,117.68730 -22.150300,117.75940 L -22.271160,103.53330 L -16.210990,105.33270 L -13.668720,112.98610 C -10.726740,113.57150 -4.8534030,116.04920 -3.1684540,117.35130 L 5.2331490,114.89480 L 7.9476440,118.32620 L 5.5213240,125.97050 C 7.0497570,127.97020 8.7094360,130.80150 9.7891030,134.13290 L 21.691340,138.06020 z " + style="fill:url(#linearGradient2884);stroke:#0d0d0d;stroke-width:0.0000000;" + id="path995" /> + + <text + id="text902" /> + + <path + d="M 3.0000000,134.75000 L 3.0000000,146.75000 L 5.7500000,147.31250 L 5.6875000,143.00000 L 8.6875000,146.43750 L 11.312500,145.62500 L 7.0625000,140.75000 L 11.375000,136.06250 L 8.8125000,135.00000 L 5.6875000,138.87500 L 5.7500000,134.12500 L 3.0000000,134.75000 z " + style="fill:none;fill-rule:evenodd;stroke:url(#linearGradient2841);stroke-width:0.60000002;" + id="path997" /> + + <text + id="text904" /> + + </g> + + <text + id="text905" /> + + <path + d="M 58.305080,192.18810 C 58.546880,190.66730 58.922850,190.21980 59.231730,189.23570 C 59.462350,190.28230 59.894220,190.85930 59.923600,192.37550 C 59.748880,193.83920 59.439990,194.43090 59.198190,195.45870 C 58.900490,194.36850 58.502160,194.01620 58.305080,192.18810 z " + transform="matrix(0.718454,-0.695575,0.695575,0.718454,-94.57463,111.3119)" + style="fill:url(#radialGradient2930);fill-rule:evenodd;stroke:#000000;stroke-width:0.0000000;" + id="path1000" /> + + <text + id="text907" /> + + <path + d="M 80.394030,186.70670 C 83.445490,189.66440 83.521210,194.53550 80.563660,197.58670 C 78.281840,199.94080 74.861480,200.52190 72.016150,199.30720 C 71.943560,199.42440 71.874780,199.53530 71.837130,199.59660 C 74.885660,200.91330 78.465640,200.20840 80.783040,197.81760 C 83.863130,194.63990 83.783760,189.54910 80.605880,186.46880 C 78.229010,184.16490 74.643620,183.56390 71.647180,184.95110 C 71.682590,185.01120 71.748840,185.12390 71.819080,185.24300 C 74.621120,183.95320 78.046280,184.43100 80.393920,186.70650 L 80.394030,186.70670 z " + transform="matrix(0.718454,-0.695575,0.695575,0.718454,-94.57463,111.3119)" + style="fill:none;stroke-width:0.0000000;" + id="path1002" /> + + <text + id="text909" /> + + </g> + +</svg> diff --git a/src/renderer.cpp b/src/renderer.cpp new file mode 100644 index 0000000..79a38d0 --- /dev/null +++ b/src/renderer.cpp @@ -0,0 +1,1028 @@ +/*************************************************************************** + File: renderer.cpp + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +// Mine +#include "renderer.h" +#include "swordoptions.h" +#include "ks_osishtml.h" +#include "ks_gbfhtml.h" +#include "ks_thmlhtml.h" +#include "utils.h" +#include "swordutils.h" +#include "template.h" + +// Sword +#include <swmgr.h> +#include <swkey.h> +#include <versekey.h> +#include <treekey.h> +#include <treekeyidx.h> +#include <plainhtml.h> +#include <rtfhtml.h> +#include <encfiltmgr.h> +#include <localemgr.h> +#include <regex.h> + + +// KDE +#include <klocale.h> + +// QT +#include <qstring.h> +#include <qstringlist.h> + +// Standard C/C++ +#include <vector> +#include <cstring> +#include <set> + + +using std::string; +using std::vector; +using std::set; +using std::list; + +using namespace sword; + +namespace KioSword +{ + static const QString prev(" <li><a href=\"%2\" accesskey=\"p\">« %1</a>"); + static QString makePrevLink(const QString& caption, const QString& url) + { + return prev.arg(caption).arg(url); + } + + static const QString next(" <li><a href=\"%2\" accesskey=\"n\">%1 »</a>"); + static QString makeNextLink(const QString& caption, const QString& url) + { + return next.arg(caption).arg(url); + } + + static const QString treeup(" <li><a href=\"%3\" accesskey=\"u\">%1 %2</a>"); + static QString makeTreeUpLink(const QString& caption1, const QString& caption2, const QString& url) + { + return treeup.arg(caption1).arg(caption2).arg(url); + } + + static const QString bibleup(" <li><a href=\"%2\" accesskey=\"u\">%1</a>"); + static QString makeBibleUpLink(const QString& caption, const QString& url) + { + return bibleup.arg(caption).arg(url); + } + + static const QString genlink(" <li><a href=\"%2\">%1</a>"); + static QString makeGeneralLink(const QString& caption, const QString& url) + { + return genlink.arg(caption).arg(url); + } + + Renderer::Renderer() : + sword::SWMgr(0, 0, true, new sword::EncodingFilterMgr(sword::ENC_UTF8)), + m_osisfilter(0), + m_gbffilter(0), + m_thmlfilter(0), + m_plainfilter(0), + m_rtffilter(0) + { + for (int i = 0; i < NUM_MODULE_TYPES; i++) { + m_moduleTypes.push_back(""); + m_moduleTypeNames.push_back(QString("")); + } + + m_moduleTypes[BIBLE] = "Biblical Texts"; + m_moduleTypes[COMMENTARY] = "Commentaries"; + m_moduleTypes[LEXDICT] = "Lexicons / Dictionaries"; + m_moduleTypes[GENERIC] = "Generic Books"; + + m_moduleTypeNames[BIBLE] = i18n("Bibles"); + m_moduleTypeNames[COMMENTARY] = i18n("Commentaries"); + m_moduleTypeNames[LEXDICT] = i18n("Lexicons & Dictionaries"); + m_moduleTypeNames[GENERIC] = i18n("Other Books"); + } + + + Renderer::~Renderer() { + delete m_osisfilter; + delete m_gbffilter; + delete m_thmlfilter; + delete m_plainfilter; + delete m_rtffilter; + } + + + void Renderer::setOptions(const SwordOptions& options) { + setGlobalOption("Footnotes", (options.footnotes() ? "On" : "Off")); + setGlobalOption("Headings", (options.headings() ? "On" : "Off")); + setGlobalOption("Strong's Numbers", (options.strongs() ? "On" : "Off")); + setGlobalOption("Morphological Tags", (options.morph() ? "On" : "Off")); + setGlobalOption("Hebrew Cantillation", (options.cantillation() ? "On" : "Off")); + setGlobalOption("Hebrew Vowel Points", (options.hebrewVowelPoints() ? "On" : "Off")); + setGlobalOption("Greek Accents", (options.greekAccents() ? "On" : "Off")); + setGlobalOption("Lemmas", (options.lemmas() ? "On" : "Off")); + setGlobalOption("Cross-references", (options.crossRefs() ? "On" : "Off")); + setGlobalOption("Words of Christ in Red",(options.redWords() ? "On" : "Off")); + + + if (options.variants() == -1) + setGlobalOption("Variants", "All Readings"); + else if (options.variants() == 1) + setGlobalOption("Variants", "Secondary Readings"); + else + setGlobalOption("Variants", "Primary Readings"); + + LocaleMgr::systemLocaleMgr.setDefaultLocaleName(options.locale()); + } + + /** Return an HTML hyperlinked list of all modules, + * categorised, and including descriptions + */ + QString Renderer::listModules(const SwordOptions &options) { + QString output; + QString temp; + ModMap::iterator it; + vector<const char *>::size_type i; + SWModule *curMod; + + setOptions(options); + + if (Modules.empty()) { + output += ("<p>" + i18n("No modules installed!") + "</p>\n"); + return output; + } + + output += QString("<div class='moduleslist'><h1>%1</h1>") + .arg(i18n("Modules")); + + for (i = 0; i < m_moduleTypes.size(); i++) { + output += QString("<h2 class='moduletype'>%1</h2>\n" + "<ul>\n").arg(m_moduleTypeNames[i]); + for (it = Modules.begin(); it != Modules.end(); it++) { + curMod = (*it).second; + if (!strcmp(curMod->Type(), m_moduleTypes[i])) { + output += QString("<li class='module'><a class='module' href=\"%3\">%1</a> : %2\n") + .arg(curMod->Name()) + .arg(curMod->Description()) + .arg(swordUrl(curMod->Name(), options)); + } + } + output += "</ul>"; + } + output += "</div>"; + return output; + } + + /** Return a sorted list of all module names + * + */ + QStringList Renderer::moduleList() { + QStringList output; + ModMap::iterator it; + SWModule *curMod; + + for (it = Modules.begin(); it != Modules.end(); it++) { + curMod = (*it).second; + output += QString(curMod->Name()); + } + output.sort(); + return output; + } + + Renderer::ModuleType Renderer::getModuleType(sword::SWModule *module) { + ModuleType modtype; + vector<const char *>::size_type i; + + modtype = GENERIC; // default + for (i = 0; i < m_moduleTypes.size(); i++) { + if (!strcmp(module->Type(), m_moduleTypes[i])) { + modtype = (ModuleType)i; + break; + } + } + return modtype; + } + + + /** Add the relevant filter to a module + * + * This method checks to see whether we've already added + * the Render filter to a module. If so, then don't + * create or attach another, but ensure the options used + * + */ + void Renderer::setModuleFilter(SWModule *module, const SwordOptions* options) { + SectionMap::iterator sit; + ConfigEntMap::iterator eit; + SWTextMarkup modformat = FMT_UNKNOWN; + SWBuf encoding; + SWFilter *filter = 0; + + if (m_modset.find(module) != m_modset.end()) + // already added + return; + + + // From corediatheke.cpp + if ((sit = config->Sections.find(module->Name())) != config->Sections.end()) { + if ((eit = (*sit).second.find("SourceType")) != (*sit).second.end()) { + if (!strcasecmp((char *)(*eit).second.c_str(), "GBF")) + modformat = FMT_GBF; + else if (!strcasecmp((char *)(*eit).second.c_str(), "ThML")) + modformat = FMT_THML; + else if (!strcasecmp((char *)(*eit).second.c_str(), "OSIS")) + modformat = FMT_OSIS; + } + // FIXME - do something with this + if ((eit = (*sit).second.find("Encoding")) != (*sit).second.end()) + encoding = (*eit).second; + else + encoding = (SWBuf)""; + } + + + switch (modformat) + { + // TODO - all filters used should subclass + // FilterBase and know how to write + // KioSword urls correctly using SwordOptions + case FMT_UNKNOWN : + case FMT_PLAIN : + if (!m_plainfilter) + m_plainfilter = new PLAINHTML(); + filter = m_plainfilter; + break; + + case FMT_THML : + if (!m_thmlfilter) + m_thmlfilter = new ThMLHTML(); + m_thmlfilter->setSwordOptions(options); + filter = m_thmlfilter; + break; + + case FMT_GBF: + if (!m_gbffilter) + m_gbffilter = new GBFHTML(); + m_gbffilter->setSwordOptions(options); + filter = m_gbffilter; + break; + + case FMT_HTML: + break; + + case FMT_HTMLHREF: + break; + + case FMT_RTF: + if (!m_rtffilter) + m_rtffilter = new RTFHTML(); + filter = m_rtffilter; + break; + + case FMT_OSIS: + if (!m_osisfilter) + m_osisfilter = new OSISHTML(); + m_osisfilter->setSwordOptions(options); + filter = m_osisfilter; + break; + + case FMT_WEBIF: + break; + + default: + break; + } + + if (filter) { + module->AddRenderFilter(filter); + m_modset.insert(m_modset.begin(), module); + } + + } + + void Renderer::moduleQuery(const QString &modname, const QString &ref, const SwordOptions &options, Template* tmplt) { + QString nav; + SWModule *module = 0; + SWKey *skey = 0; + KeyType keyt = SWKEY; + VerseKey *vk; + TreeKey *tk; + + ModuleType modtype; + + // Set the sword::Mgr options + setOptions(options); + + // Find the module + module = getModule(modname.latin1()); + + if (module == 0) { + QString output; + output += "<p><span class='error'>" + + i18n("The module '%1' could not be found.").arg(modname) + + "</span></p><hr/>"; + output += listModules(options); + tmplt->setContent(output); + tmplt->setTitle(i18n("Module not found - Kio-Sword")); + } + else + { + setModuleFilter(module, &options); + + // Determine key type. + skey = module->getKey(); + if (!(vk = dynamic_cast<VerseKey*>(skey))) { + if (!(tk = dynamic_cast<TreeKey*>(skey))) { + keyt = SWKEY; + } else { + keyt = TREEKEY; + } + } else { + keyt = VERSEKEY; + } + modtype = getModuleType(module); + + nav += QString("<li class='first'>%1 <a href=\"%3\">%2</a></li>") + .arg(i18n("Module:")) + .arg(modname) + .arg(swordUrl(modname, options)); + + if (keyt == VERSEKEY) { // Should be just bibles and commentaries + verseQuery(module, ref, options, modtype, tmplt, nav); + } else if (keyt == TREEKEY) { + treeQuery(module, ref, options, modtype, tmplt, nav); + } else if (keyt == SWKEY) { + normalQuery(module, ref, options, modtype, tmplt, nav); + } + tmplt->setNav("<ul>" + nav + "</ul>"); + tmplt->setShowToggles(true); + } + return; + } + + QString Renderer::search(const QString &modname, const QString &query, const SearchType searchType, const SwordOptions &options) { + SWModule *module = 0; + QString output; + ListKey lk; + int stype = SEARCH_WORDS; + QString stypename; + ModuleType modtype; + + setOptions(options); + + // Find the module + module = getModule(modname.latin1()); + + if (module == 0) { + output += "<p><span class='error'>" + + i18n("The module '%1' could not be found.").arg(modname) + + "</span></p>"; + output += listModules(options); + return output; + } + + modtype = getModuleType(module); + + if (searchType == SEARCH_WORDS) { + stype = -2; + stypename = i18n("Word"); + } else if (searchType == SEARCH_PHRASE) { + stype = -1; + stypename = i18n("Phrase"); + } else if (searchType == SEARCH_REGEX) { + stype = 0; + stypename = i18n("Regular expression"); + } + + output += "<div class='searchresults'><h1>" + i18n("Search results:") + "</h1>"; + output += QString("<table><tr><td>%1</td><td><b>%2</b></td></tr><tr><td>%3</td><td><b>%4</b></td></tr><tr><td>%5</td><td><b>%6</b></td></tr></table>") + .arg(i18n("Module:")) + .arg(modname) + .arg(i18n("Query:")) + .arg(query) + .arg(i18n("Search type:")) + .arg(stypename); + + + lk = module->search(query.utf8(), stype, REG_ICASE); + if (lk.Count() == 0) { + output += "<p>" +i18n("No matches returned."); + } else { + output += "<p>" + i18n("1 match returned:", "%1 matches returned:", lk.Count()).arg(lk.Count()); + output += "<ul>"; + for (int i = 0; i < lk.Count(); ++i) { + QString ref; + ref = QString::fromUtf8(lk.getElement(i)->getText()); + if (modtype == BIBLE) { + module->setKey(lk.getElement(i)); + output += QString("<li><a href=\"%3\">%1</a>: %2</li>") + .arg(ref) + .arg(renderText(module)) + .arg(swordUrl(modname, ref, options)); + + } else { + output += QString("<li><a href=\"%2\">%1</a></li>") + .arg(ref) + .arg(swordUrl(modname, ref, options)); + } + } + output += "</ul>"; + } + output += "</div>"; + return output; + } + + QString Renderer::renderText(SWModule *module) { + return QString::fromUtf8(module->RenderText()); + } + + /** Fill in template with formatted text for the query of a verse based module + * Links are appended to navlinks. + */ + void Renderer::verseQuery(SWModule *module, const QString &ref, const SwordOptions &options, + ModuleType modtype, Template* tmplt, QString &navlinks) { + QString modname(module->Name()); + QString text; + bool doindex = false; + const char* modtextdir; // text direction of the module + + ListKey lk; + VerseKey *vk = dynamic_cast<VerseKey*>(module->getKey()); + + if (!vk) + return; + + // FIXME - why do I need this call to setLocale()? + vk->setLocale(LocaleMgr::systemLocaleMgr.getDefaultLocaleName()); + + modtextdir = textDirection(module); + + vk->AutoNormalize(0); + do { // dummy loop + if (ref.isEmpty()) { + doindex = true; + break; + } + lk = vk->ParseVerseList(ref, "Genesis 1:1", true); + if (lk.Count() == 0) { + text += "<p class=\"error\">" + i18n("Couldn't find reference '%1'.").arg(ref) + "</p>"; + doindex = true; + break; + } + char book = 0; + char testament = 0; + int chapter = 0; + bool upToBookListShown = false; + for (int i = 0; i < lk.Count(); ++i) { + VerseKey *element = dynamic_cast<VerseKey*>(lk.GetElement(i)); + if (element) { + // Multiple verses + char err = 0; + + // Check whether we have an entire book selected + // (but treat single chapter books as if they were just + // one chapter from a book) + if (element->UpperBound().Chapter() > 1 && + isEntireBook(element) && !options.wholeBook()) { + // List books and link for viewing entire book + SwordOptions options_wholebook(options); + options_wholebook.wholeBook.set(true); // set just for creating the URL + text += QString("<h2>%1</h2>" + "<p>%2</p>" + "<p class='chapterlist'>%3</p>") + .arg(element->getBookName()) + .arg(i18n("Chapters:")) + .arg(chapterList(modname, element, options)) + + QString("<p><a href=\"%2\">%1</a></p>") + .arg(i18n("View entire book.")) + .arg(swordUrl(module->Name(), element->getBookName(), options_wholebook)); + if (!upToBookListShown) + { + navlinks += makeBibleUpLink(i18n("Books"), + swordUrl(modname, options)); + upToBookListShown = true; + } + } else { + // chapter or verse range selected + module->Key(element->LowerBound()); + if (lk.Count() == 1) { + // add some navigation links + if (isSingleChapter(element)) { + // get link to previous chapter + module->decrement(); + if (!module->Error()) { + navlinks += makePrevLink(bookChapter(module->getKey()), + chapterLink(modname, module->getKey(), options)); + } + // get link to book + module->Key(element->LowerBound()); + navlinks += makeBibleUpLink(bookName(element), + bookLink(modname, element, options)); + } else { + // less than a single chapter + // get link to book + navlinks += makeGeneralLink(bookName(element), + bookLink(modname, element, options)); + // get link to chapter + navlinks += makeBibleUpLink(bookChapter(element), + chapterLink(modname, element, options)); + } + } + + // Headings plus text itself + bool inDirectionedDiv = false; + do { + VerseKey *curvk = dynamic_cast<VerseKey*>(module->getKey()); + if (curvk->Book() != book || curvk->Testament() != testament) { + if (inDirectionedDiv) + { + // close it before carrying on + text += "</div>"; + inDirectionedDiv = false; + } + text += "<h2>" + QString(curvk->getBookName()) + "</h2>"; + chapter = 0; + } + if (curvk->Chapter() != chapter) { + if (inDirectionedDiv) + { + // close it before carrying on + text += "</div>"; + inDirectionedDiv = false; + } + text += "<h3>" + i18n("Chapter %1").arg(curvk->Chapter()) + "</h3>"; + } + + if (!inDirectionedDiv) { + text += QString("<div dir='%1'>").arg(modtextdir); + inDirectionedDiv = true; + } + + if (options.verseNumbers() && modtype == BIBLE) { + text += QString("<a class=\"versenumber\" href=\"%2\">%1</a> ") + .arg(curvk->Verse()) + .arg(swordUrl(module->Name(), module->KeyText(), options)); + } + text += renderText(module); + text += " "; + if (options.verseLineBreaks()) + text += "<br />"; + book = curvk->Book(); + testament = curvk->Testament(); + chapter = curvk->Chapter(); + + module->increment(1); + } while (module->Key() <= element->UpperBound() && !(err = module->Error())); + + // Close the final div + if (inDirectionedDiv) + { + text += "</div>"; + inDirectionedDiv = false; + } + + if (lk.Count() == 1) { + if (isSingleChapter(element)) { + // add some navigation links + if (!err) { + navlinks += makeNextLink(bookChapter(module->getKey()), + chapterLink(modname, module->getKey(), options)); + } + } + } + } + } else { + // Reset flags used by the multiple verse path + book = 0; + testament = 0; + chapter = 0; + // Single verse + module->Key(*lk.GetElement(i)); + element = dynamic_cast<VerseKey*>(module->getKey()); + text += QString("<h3>%1</h3>").arg(module->KeyText()); + text += QString("<div dir='%1'>").arg(modtextdir); + text += renderText(module); + text += "</div>"; + if (lk.Count() == 1) + navlinks += makeBibleUpLink(bookChapter(element), + chapterLink(modname, element, options)); + } + if (i+1 != lk.Count()) + text += "<br />"; + } + } while (false); + + // Title: depends on what got printed above + QString title; + if (doindex) { + if (!text.isEmpty()) { // an error message was printed + text = QString("<h1 class=\"moduletitle\">%1</h1>").arg(module->Description()).arg(ref) + + text; + title = "Error - Kio-Sword"; + } + else + { + title = QString("%1 - Kio-Sword").arg(module->Name()); + } + } else { + if (modtype == COMMENTARY) { + text = QString("<h1 class=\"moduletitle\">%1</h1>").arg(module->Description()) + + text; + title = QString("%1 - %2 - Kio-Sword") + .arg(lk.getShortText()) + .arg(module->Name()); + } else if (modtype == BIBLE) { + text += QString("<div class=\"biblename\">(%1)</div>").arg(module->Description()); + title = QString("%1 - %2 - Kio-Sword") + .arg(lk.getShortText()) + .arg(module->Name()); + } + } + tmplt->setTitle(title); + + if (doindex) { + if (!text.isEmpty()) + text += "<hr/>\n"; + if (options.doBibleIndex()) { + text += "<h2>" + i18n("Books:") + "</h2>"; + text += indexBible(module, options); + } else { + SwordOptions options_doindex(options); + options_doindex.doBibleIndex.set(true); + text += QString("<p><a href=\"%2\">%1</a></p>") + .arg(i18n("Index of books")) + .arg(swordUrl(modname, options_doindex)); + } + } + tmplt->setContent(text); + } + + void Renderer::treeQuery(SWModule *module, const QString &ref, const SwordOptions &options, + ModuleType modtype, Template* tmplt, QString &navlinks) { + QString output; + QString modname(module->Name()); + bool doindex; + TreeKey *tk = dynamic_cast<TreeKey*>(module->getKey()); + + if (!tk) + return; + + output += QString("<h1 class=\"moduletitle\">%1</h1>").arg(module->Description()); + if (ref.isEmpty()) { + doindex = true; + } else { + tk->Error(); // clear + tk->setText(ref.utf8()); + doindex = false; + if (tk->Error()) { + output += "<p class=\"error\">" + i18n("Couldn't find section '%1'.").arg(ref) + "</p>"; + output += "<hr/>"; + doindex = true; + } else { + QString link; + output += renderText(module); + if (tk->previousSibling()) { + link = QString::fromUtf8(module->KeyText()); // FIXME ? local8Bit or utf8 + navlinks += makePrevLink(shorten(link.section('/', -1, -1), 20), + swordUrl(modname, link, options)); + tk->nextSibling(); + } + SWKey *saved = tk->clone(); + if (tk->parent()) { + link = QString::fromUtf8(module->KeyText()); + navlinks += makeTreeUpLink(i18n("Up:"), + shorten(link.section('/', -1, -1), 20), + swordUrl(modname, link, options)); + tk->copyFrom(*saved); + } + delete saved; + if (tk->nextSibling()) { + link = QString::fromUtf8(module->KeyText()); + navlinks += makeNextLink(shorten(link.section('/', -1, -1), 20), + swordUrl(modname, link, options)); + tk->previousSibling(); + } + if (tk->hasChildren()) { + if (tk->firstChild()); + output += "<hr/>"; + output += indexTree(module, options, false, 1); + } + } + } + + if (doindex) { + output += "<h2>" + i18n("Contents:") + "</h2>"; + SwordOptions options_doindex(options); + if (options.doFullTreeIndex()) { + options_doindex.doFullTreeIndex.set(false); + output += indexTree(module, options, true, -1); + output += QString("<p><a href=\"%2\">%1</a></p>") + .arg(i18n("View simple index")) + .arg(swordUrl(modname, options_doindex)); + } else { + options_doindex.doFullTreeIndex.set(true); + output += indexTree(module, options, true, 1); + output += QString("<p><a href=\"%2\">%1</a></p>") + .arg(i18n("View full index")) + .arg(swordUrl(modname, options_doindex)); + } + tmplt->setTitle(QString("%1 - %2 - Kio-Sword").arg(tk->getShortText()).arg(module->Name())); + } + else + { + tmplt->setTitle(QString("%1 - Kio-Sword").arg(module->Name())); + } + tmplt->setContent(output); + + + } + + void Renderer::normalQuery(SWModule *module, const QString &ref, const SwordOptions &options, + ModuleType modtype, Template* tmplt, QString &navlinks) { + QString output; + QString modname(module->Name()); + bool doindex; + SWKey *skey = module->getKey(); + + output += QString("<h1 class=\"moduletitle\">%1</h1>").arg(module->Description()); + + if (ref.isEmpty()) { + doindex = true; + } else { + skey->Error(); // clear + skey->setText(ref.utf8()); + doindex = false; + if (skey->Error()) { + output += "<p class=\"error\">" + QString(i18n("Couldn't find reference '%1'.")).arg(ref) + "</p>"; + output += "<hr>"; + doindex = true; + } else { + output += QString("<h3>%1</h3>").arg(module->KeyText()); + output += renderText(module); + module->decrement(); + QString link; + if (!module->Error()) { + link = module->KeyText(); + navlinks += makePrevLink(link, swordUrl(modname, link, options)); + module->increment(); + } + module->increment(); + if (!module->Error()) { + link = module->KeyText(); + navlinks += makeNextLink(link, swordUrl(modname, link, options)); + module->decrement(); + } + } + } + + if (doindex) { + if (((modtype == LEXDICT) && options.doDictIndex()) || + ((modtype == GENERIC) && options.doOtherIndex())) { + output += "<h2>" + i18n("Index:") + "</h2>"; + output += indexBook(module, options); + } else { + + output += QString("<form action='%2' method='get'>" + "%1 <input type='text' name='query'>" + "</form>") + .arg(i18n("Enter query term: ")) + .arg(swordUrl(modname, options)); + + SwordOptions options_doindex(options); + options_doindex.doDictIndex.set(true); + options_doindex.doOtherIndex.set(true); + output += QString("<p><a href=\"%2\">%1</a></p>") + .arg(i18n("View complete index")) + .arg(swordUrl(modname, options_doindex)); + } + tmplt->setTitle(QString("%1 - Kio-Sword").arg(module->Name())); + } + else + { + tmplt->setTitle(QString("%1 - %2 - Kio-Sword").arg(skey->getShortText()).arg(module->Name())); + } + tmplt->setContent(output); + } + + /** Retrieves an HTML list of all the books in the module + * + * @param module The module to retrieve. Must be a Bible/commentary + */ + + QString Renderer::indexBible(SWModule *module, const SwordOptions& options) { + QString output; + char book; + char testament; + VerseKey *vk = dynamic_cast<VerseKey*>(module->getKey()); + + if (!vk) + return output; + vk->setLocale(LocaleMgr::systemLocaleMgr.getDefaultLocaleName()); + + module->setSkipConsecutiveLinks(true); + vk->AutoNormalize(1); + module->setPosition(sword::TOP); + + book = vk->Book(); + testament = vk->Testament(); + + output += "<ul>\n"; + while (vk->Testament() == testament) { + while (vk->Book() == book && !module->Error()) { + output += QString("<li><a href=\"%2\">%1</a>\n") + .arg(vk->getBookName()) + .arg(swordUrl(module->Name(), vk->getBookName(), options)); + vk->Book(++book); + }; + // Move to new testament, if not there already. + ++testament; + module->setPosition(sword::BOTTOM); + book = 1; + vk->Book(book); + }; + output += "</ul>\n"; + module->setSkipConsecutiveLinks(false); + return output; + } + + + /** Retrieves an HTML list of all the keys in a module + * + * @param module The module to retrieve. Must have key type SWKey + */ + + QString Renderer::indexBook(SWModule *module, const SwordOptions& options) { + QString output; + QString ref; + + module->setPosition(sword::TOP); + output += "<ul>\n"; + do { + ref = QString::fromUtf8(module->KeyText()); + output += QString("<li><a href=\"%2\">%1</a></li>") + .arg(ref) + .arg(swordUrl(module->Name(), ref, options)); + (*module)++; + } while(!module->Error()) ; + output += "</ul>\n"; + return output; + } + + /** Return the index of a tree-key based module + * + * @param module The module to scan + * @param fromTop If true, get the index from the top level + * @param depth How many levels to scan, -1 for all + */ + QString Renderer::indexTree(SWModule *module, const SwordOptions& options, bool fromTop, const int depth) { + QString output; + QString ref; + bool gonext; + bool cont; + + TreeKey *tk = dynamic_cast<TreeKey*>(module->getKey()); + int mydepth = 1; + + if (!tk) + return output; + + if (fromTop) { + tk->root(); + tk->firstChild(); + } + + output += "<ul>"; + cont = true; + gonext = false; + do { + if (!gonext) { + ref = QString::fromUtf8(module->KeyText()); + output += QString("<li><a href=\"%2\">%1</a>\n") + .arg(ref.section('/', -1)) + .arg(swordUrl(module->Name(), ref, options)); + } + if (!gonext && tk->hasChildren() && (mydepth < depth || depth == -1) ) { + if (tk->firstChild()) { + mydepth++; + output += "<ul>"; + cont = true; + } else { + cont = false; + } + } else { + if (tk->nextSibling()) { + gonext = false; + cont = true; + } else { + // try to go up a level + cont = false; + if (mydepth > 1) { + if (tk->parent()) { + mydepth--; + output += "</ul>"; + cont = true; + gonext = true; + } + } + } + } + } while (cont); + + output += "</ul>"; + return output; + + } + + QString Renderer::chapterList(const QString &modname, const VerseKey *vk, const SwordOptions& options) { + VerseKey cp(vk->LowerBound()); + QString output; + do { + cp.Verse(0); + if (!output.isNull()) output += " | "; + output += QString("<a href=\"%2\">%1</a>") + .arg(cp.Chapter()) + .arg(chapterLink(modname, &cp, options)); + cp.Chapter(cp.Chapter()+1); + } while (cp.Chapter() <= vk->UpperBound().Chapter()) ; + return output; + } + + QString Renderer::chapterLink(const QString &modname, const VerseKey *vk, const SwordOptions& options) { + return swordUrl(modname, bookChapter(vk), options); + } + + QString Renderer::chapterLink(const QString &modname, const SWKey *sk, const SwordOptions& options) { + const VerseKey *vk = dynamic_cast<const VerseKey*>(sk); + if (vk) + return chapterLink(modname, vk, options); + else + return QString::null; + } + + QString Renderer::bookLink(const QString &modname, const VerseKey *vk, const SwordOptions& options) { + return swordUrl(modname, bookName(vk), options); + } + + QString Renderer::bookLink(const QString &modname, const SWKey *sk, const SwordOptions& options) { + const VerseKey *vk = dynamic_cast<const VerseKey*>(sk); + if (vk) + return bookLink(modname, vk, options); + else + return QString::null; + } + + QString Renderer::bookChapter(const VerseKey *vk) { + return QString("%1 %2").arg(vk->getBookName()).arg(vk->Chapter()); + } + + QString Renderer::bookChapter(const SWKey *sk) { + const VerseKey *vk = dynamic_cast<const VerseKey*>(sk); + if (vk) + return bookChapter(vk); + else + return QString::null; + } + + QString Renderer::bookName(const VerseKey *vk) { + return QString(vk->getBookName()); + } + + QString Renderer::bookName(const SWKey *sk) { + const VerseKey *vk = dynamic_cast<const VerseKey*>(sk); + if (vk) + return bookName(vk); + else + return QString::null; + } + + QStringList Renderer::availableLocales() + { + list<SWBuf> locales = LocaleMgr::systemLocaleMgr.getAvailableLocales(); + list<SWBuf>::const_iterator it; + list<SWBuf>::const_iterator it_end = locales.end(); + QStringList output; + for (it = locales.begin(); it != it_end; it++) + { + output.append(QString((*it).c_str())); + } + return output; + } +} diff --git a/src/renderer.h b/src/renderer.h new file mode 100644 index 0000000..d3e398f --- /dev/null +++ b/src/renderer.h @@ -0,0 +1,131 @@ +/*************************************************************************** + File: renderer.h + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef KS_RENDERER_H +#define KS_RENDERER_H + +#include "filter.h" + +#include <swmgr.h> +#include <swmodule.h> +#include <versekey.h> + +#include <qstring.h> +#include <qstringlist.h> + +#include <functional> +#include <vector> +#include <set> + + +/** Handles sword backend and prints modules + * + * Renderer inherits from sword::SWMgr and handles the majority of + * the sword stuff. It also adds functions to 'print' text from + * a specified module and to list available modules. + * + * All output is in HTML, and unicode characters are not converted + * to HTML entities (this allows the calling function to decide + * what encoding to use in the web page e.g. utf 8 could be used + * and no transformation would need to be done). + * + */ + +namespace KioSword { + class SwordOptions; + class Template; + + class Renderer : public sword::SWMgr { + + public: + Renderer(); + virtual ~Renderer(); + + typedef enum { SEARCH_WORDS, + SEARCH_PHRASE, + SEARCH_REGEX } SearchType; + + /** Return an HTML snippet of specified key from module + * + * @param module The sword module to print from + * @param key The text description of the key from the users URL + * @param options Options for rendering text + * @param tmplt Output parameter that should be filled with title and content + */ + void moduleQuery(const QString &module, const QString &ref, const SwordOptions &options, Template* tmplt); + + QString search(const QString &module, const QString &query, SearchType stype, const SwordOptions &options); + + /** Return an HTML snippet containing a hyperlinked table of modules + */ + QString listModules(const SwordOptions &options); + void setOptions(const SwordOptions &options); + QStringList moduleList(); + QStringList availableLocales(); + + + protected: + typedef enum { BIBLE, COMMENTARY, LEXDICT, GENERIC, NUM_MODULE_TYPES } ModuleType ; + enum KeyType { SWKEY, VERSEKEY, TREEKEY } ; + void setModuleFilter(sword::SWModule *module, const SwordOptions* options); + + ModuleType getModuleType(sword::SWModule *module); + QString indexBible(sword::SWModule *module, const SwordOptions& options); + QString indexBook(sword::SWModule *module, const SwordOptions& options); + QString indexTree(sword::SWModule *module, const SwordOptions& options, bool fromTop, const int depth = -1); + + void verseQuery(sword::SWModule *module, const QString &query, const SwordOptions &options, + ModuleType modtype, Template* tmplt, QString &navlinks); + void treeQuery(sword::SWModule *module, const QString &query, const SwordOptions &options, + ModuleType modtype, Template* tmplt, QString &navlinks); + void normalQuery(sword::SWModule *module, const QString &query, const SwordOptions &options, + ModuleType modtype, Template* tmplt, QString &navlinks); + + static QString renderText(sword::SWModule *module); + static QString chapterList(const QString &modname, const sword::VerseKey *vk, const SwordOptions& options); + + static QString chapterLink(const QString &modname, const sword::VerseKey *vk, const SwordOptions& options); + static QString chapterLink(const QString &modname, const sword::SWKey *sk, const SwordOptions& options); + + static QString bookLink(const QString &modname, const sword::VerseKey *vk, const SwordOptions& options); + static QString bookLink(const QString &modname, const sword::SWKey *sk, const SwordOptions& options); + + static QString bookChapter(const sword::SWKey *sk); + static QString bookChapter(const sword::VerseKey *vk); + + static QString bookName(const sword::SWKey *sk); + static QString bookName(const sword::VerseKey *vk); + + FilterBase *m_osisfilter; + FilterBase *m_gbffilter; + FilterBase *m_thmlfilter; + sword::SWFilter *m_plainfilter; + sword::SWFilter *m_rtffilter; + + std::set<sword::SWModule *, std::less<sword::SWModule *> > m_modset; + std::vector<const char *> m_moduleTypes; + std::vector<QString> m_moduleTypeNames; + + }; +} +#endif // KS_RENDERER_H + diff --git a/src/sword.protocol b/src/sword.protocol new file mode 100644 index 0000000..ab82dcf --- /dev/null +++ b/src/sword.protocol @@ -0,0 +1,13 @@ +[Protocol] +exec=kio_sword +protocol=sword +input=none +output=filesystem +reading=true +defaultMimetype=text/html +Icon=kio_sword +Description=A kioslave for quick access to Bible texts within Konqueror +DocPath=kio_sword/index.html +determineMimetypeFromExtension=false +Class=:local +URIMode=uri diff --git a/src/swordoptions.cpp b/src/swordoptions.cpp new file mode 100644 index 0000000..306e548 --- /dev/null +++ b/src/swordoptions.cpp @@ -0,0 +1,174 @@ +/*************************************************************************** + File: swordoptions.cpp + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +// Internal +#include "swordoptions.h" +#include "option.h" + + +// Std C/C++ +#include <vector> +#include <stdlib.h> + +using std::vector; + +namespace KioSword +{ + SwordOptions::SwordOptions() + { + init(); + } + + void SwordOptions::init() + { + // Setup all the options + propagate.setup (true, "PropagateOptions", "p", "propagate", true); + verseNumbers.setup (true, "VerseNumbers", "vn", "versenumbers", true); + verseLineBreaks.setup (true, "VerseLineBreaks", "lb", "linebreaks", true); + redWords.setup (true, "RedWords", "rw", "redwords", true); + footnotes.setup (false, "Footnotes", "fn", "footnotes", true); + headings.setup (true, "Headings", "hd", "headings", true); + strongs.setup (false, "StrongsNumbers", "st", "strongs", true); + morph.setup (false, "MorphologicalTags", "mt", "morph", true); + cantillation.setup (true, "Cantillation", "hc", "cantillation", true); + hebrewVowelPoints.setup (true, "HebrewVowelPoints", "hvp", "vowelpoints", true); + greekAccents.setup (true, "GreekAccents", "ga", "accents", true); + styleSheet.setup ("default.css", "StyleSheet", "ss", "stylesheet", true); + variants.setup (0, "Variants", "vr", "variants", true); + wholeBook.setup (false, "WholeBook", "wb", "wholebook", false); + doBibleIndex.setup (true, "BibleIndex", "bi", "bibleindex", false); + doDictIndex.setup (false, QString::null, "di", "dictindex", false); + doFullTreeIndex.setup (false, "FullTreeIndex", "fi", "fullindex", false); + doOtherIndex.setup (false, QString::null, "oi", "otherindex", false); + defaultBible.setup ("", "DefaultBible", "dfb", "defaultbible", true); + defaultGreekStrongs.setup ("", "DefaultGreekStrongs", "dfgs", "defaultgreekstrongs", true); + defaultHebrewStrongs.setup ("", "DefaultHebrewStrongs", "dfhs", "defaulthebrewstrongs", true); + defaultGreekMorph.setup ("", "DefaultGreekMorph", "dfgm", "defaultgreekmorph", true); + defaultHebrewMorph.setup ("", "DefaultHebrewMorph", "dfhm", "defaulthebrewmorph", true); + locale.setup ("", "Locale", "l", "locale", true); + + m_optionList.push_back(&propagate); + m_optionList.push_back(&verseNumbers); + m_optionList.push_back(&verseLineBreaks); + m_optionList.push_back(&redWords); + m_optionList.push_back(&footnotes); + m_optionList.push_back(&headings); + m_optionList.push_back(&strongs); + m_optionList.push_back(&morph); + m_optionList.push_back(&cantillation); + m_optionList.push_back(&hebrewVowelPoints); + m_optionList.push_back(&greekAccents); + m_optionList.push_back(&styleSheet); + m_optionList.push_back(&variants); + m_optionList.push_back(&wholeBook); + m_optionList.push_back(&doBibleIndex); + m_optionList.push_back(&doDictIndex); + m_optionList.push_back(&doFullTreeIndex); + m_optionList.push_back(&doOtherIndex); + m_optionList.push_back(&defaultBible); + m_optionList.push_back(&defaultGreekStrongs); + m_optionList.push_back(&defaultHebrewStrongs); + m_optionList.push_back(&defaultGreekMorph); + m_optionList.push_back(&defaultHebrewMorph); + m_optionList.push_back(&locale); + } + + /** Copy constuctor */ + SwordOptions::SwordOptions(const SwordOptions& other) + { + init(); + vector<OptionBase*>::const_iterator it_other; + vector<OptionBase*>::const_iterator it_end = other.m_optionList.end(); + + vector<OptionBase*>::const_iterator it_this = m_optionList.begin(); + for(it_other = other.m_optionList.begin(); it_other != it_end; ) + { + (*it_this)->copy((*it_other)); + ++it_this; + ++it_other; + } + } + + SwordOptions::~SwordOptions() + { + } + + /** Set all (appropriate) options from the query string */ + void SwordOptions::readFromQueryString(QMap<QString, QString> items) + { + vector<OptionBase*>::const_iterator it; + vector<OptionBase*>::const_iterator it_end = m_optionList.end(); + + for(it = m_optionList.begin(); it != it_end; ++it) + { + (*it)->readFromQueryString(items, propagate()); + } + } + + + /** Read all options in from the config file/defaults */ + void SwordOptions::readFromConfig(const KConfig* config) + { + vector<OptionBase*>::const_iterator it; + vector<OptionBase*>::const_iterator it_end = m_optionList.end(); + + for(it = m_optionList.begin(); it != it_end; ++it) + { + (*it)->readFromConfig(config); + } + } + + /** Save all options to the config file */ + void SwordOptions::saveToConfig(KConfig* config) + { + vector<OptionBase*>::const_iterator it; + vector<OptionBase*>::const_iterator it_end = m_optionList.end(); + + for(it = m_optionList.begin(); it != it_end; ++it) + { + (*it)->saveToConfig(config); + } + } + + /** Get the values that should be used for building a query string */ + QMap<QString, QString> SwordOptions::getQueryStringParams() const + { + QMap<QString, QString> result; + + + vector<OptionBase*>::const_iterator it; + vector<OptionBase*>::const_iterator it_end = m_optionList.end(); + + for(it = m_optionList.begin(); it != it_end; ++it) + { + QString name = QString::null; + QString value = QString::null; + (*it)->getQueryStringPair(name, value); + if (!name.isNull() && !name.isEmpty()) + { + result[name] = value; + } + } + return result; + } +} diff --git a/src/swordoptions.h b/src/swordoptions.h new file mode 100644 index 0000000..ee41b2f --- /dev/null +++ b/src/swordoptions.h @@ -0,0 +1,100 @@ +/*************************************************************************** + File: swordoptions.h + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef SWORDOPTIONS_H +#define SWORDOPTIONS_H + +// Internal +#include "option.h" + +// KDE +#include <kglobal.h> + +// Qt +#include <qstring.h> + + +// Std C/C++ +#include <vector> +#include <stdlib.h> + +using std::vector; + +namespace KioSword { + class SwordOptions { + + // There are 3 lists of options: + // - Here + // - 2* in SwordOptions::init() + // Also, they usually need to be added to the settings form + public: + // Need to duplicate + Option<bool> propagate; // Allow options set in one 'get' command to persist to later 'get' commands + Option<bool> redWords; + Option<bool> verseNumbers; + Option<bool> verseLineBreaks; + Option<QString> styleSheet; // FIXME IMPLEMENT + + Option<bool> footnotes; // FIXME IMPLEMENT + Option<bool> headings; // FIXME IMPLEMENT + Option<bool> strongs; + Option<bool> morph; + Option<bool> cantillation; + Option<bool> hebrewVowelPoints; + Option<bool> greekAccents; + Option<bool> lemmas; // FIXME IMPLEMENT + Option<bool> crossRefs; // FIXME IMPLEMENT + Option<int> variants; + + Option<bool> wholeBook; // Allows whole book to be printed - otherwise 'Genesis' will give an index of chapters + Option<bool> doBibleIndex; // Create an index for for Bibles/Commentaries + Option<bool> doFullTreeIndex; // Create a full index for 'tree' books, not just first level + Option<bool> doDictIndex; // Create an index for all items in a Lexicon/Dictionary + Option<bool> doOtherIndex; // Create an index for other books + + Option<QString> defaultBible; + Option<QString> defaultGreekStrongs; + Option<QString> defaultHebrewStrongs; + Option<QString> defaultGreekMorph; + Option<QString> defaultHebrewMorph; + + Option<QString> locale; + + SwordOptions(); + SwordOptions(const SwordOptions& copyFrom); + virtual ~SwordOptions(); + + void readFromConfig(const KConfig* config); + void saveToConfig(KConfig* config); + + QMap<QString, QString> getQueryStringParams() const; + void readFromQueryString(QMap<QString, QString> params); + + private: + /** options that are read/saved in the config or propagated */ + vector<OptionBase*> m_optionList; + void init(); + + }; +} +#endif diff --git a/src/swordutils.cpp b/src/swordutils.cpp new file mode 100644 index 0000000..8b5960c --- /dev/null +++ b/src/swordutils.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + File: swordutils-.cpp + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "swordutils.h" +#include <versekey.h> + +using namespace sword; +using sword::VerseKey; +using sword::SWModule; + +namespace KioSword { + + /** \brief Return true if the verse key specifies an entire book of the Bible + * + */ + bool isEntireBook(const VerseKey *vk) { + if (vk->LowerBound().Chapter() == 1 && + vk->LowerBound().Verse() == 1) { + // lower bound is first verse in book + VerseKey cp(vk->UpperBound()); + cp++; + if (cp._compare(vk->UpperBound()) == 0 || + cp.Error() || + cp.Book() != vk->UpperBound().Book()) { + // reached end of module, or + // another book + return true; + } + } + return false; + } + + + /** Checks if the VerseKey represents a single chapter + * + */ + bool isSingleChapter(const VerseKey *vk) { + if (!vk) return false; + + if (vk->LowerBound().Verse() == 1 && + vk->LowerBound().Chapter() == vk->UpperBound().Chapter()) { + VerseKey cp(vk->UpperBound()); + cp++; + if (cp._compare(vk->UpperBound()) == 0 || + cp.Error() || + cp.Chapter() != vk->UpperBound().Chapter()) { + // either reached end of module, or + // another chapter + return true; + } + } + return false; + } + + + /** Gets the text direction of the given module, used for + * inserting into HTML + * + * @param module Module to test + * @return "ltr" or "rtl" + */ + const char* textDirection(SWModule* module) + { + return (module->Direction(-1) == (int)sword::DIRECTION_LTR ? "ltr" : "rtl"); + } +} diff --git a/src/swordutils.h b/src/swordutils.h new file mode 100644 index 0000000..fdccf4d --- /dev/null +++ b/src/swordutils.h @@ -0,0 +1,35 @@ +/*************************************************************************** + File: swordutils.h + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef SWORDUTILS_H +#define SWORDUTILS_H + +#include <versekey.h> +#include <swmodule.h> + +namespace KioSword { + bool isEntireBook(const sword::VerseKey *vk); + bool isSingleChapter(const sword::VerseKey *vk); + const char* textDirection(sword::SWModule* module); +} +#endif diff --git a/src/template.cpp b/src/template.cpp new file mode 100644 index 0000000..8c5090d --- /dev/null +++ b/src/template.cpp @@ -0,0 +1,175 @@ +/*************************************************************************** + File: template.cpp + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "template.h" +#include "utils.h" +#include "swordoptions.h" + +#include <kglobal.h> +#include <klocale.h> +#include <kstandarddirs.h> + +#include <qstring.h> + +namespace KioSword { + + + // placeholders + static const char* PAGETITLE = "{$pagetitle}"; + static const char* BASECSS = "{$basecss}"; + static const char* CONTENT = "{$content}"; + static const char* HOMELINK = "{$homelink}"; + static const char* HOMELINKCAPTION = "{$homelinkcaption}"; + static const char* SEARCHLINK = "{$searchlink}"; + static const char* SEARCHLINKCAPTION = "{$searchlinkcaption}"; + static const char* SETTINGSLINK = "{$settingslink}"; + static const char* SETTINGSLINKCAPTION = "{$settingslinkcaption}"; + static const char* HELPLINK = "{$helplink}"; + static const char* HELPLINKCAPTION = "{$helplinkcaption}"; + static const char* TOPNAV = "{$topnav}"; + static const char* BOTTOMNAV = "{$bottomnav}"; + static const char* TOGGLES = "{$toggles}"; + + // static HTML fragments ------------------------------------------------------------------------------------------------------- + static const QString &html_page(QString("") + + "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" " // make W3C valid + "\"http://www.w3.org/TR/html4/strict.dtd\">\n" + "<html><head>\n" + "<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>\n" + "<title>" + PAGETITLE + "</title>\n" + "<link rel=\"StyleSheet\" href=\"file:" + BASECSS + "\" TYPE=\"text/css\">\n" + "</head>\n" + "<body class=\"kiosword\">" + "<div class=\"page\"><div class='inner'>" + " " + TOPNAV + "\n" + " <div class=\"content\"><div class='inner'>" + CONTENT + "</div></div>\n" + " " + TOGGLES + "\n" + " " + BOTTOMNAV + "\n" + " <div class=\"links\"><div class='inner'>\n" + " <ul>\n" + " <li><a accesskey=\"t\" href=\"" + HOMELINK + "\">" + HOMELINKCAPTION + "</a></li>\n" + " <li><a href=\"" + SEARCHLINK + "\">" + SEARCHLINKCAPTION + "</a></li>\n" + " <li><a href=\"" + SETTINGSLINK + "\">" + SETTINGSLINKCAPTION + "</a></li>\n" + " <li><a href=\"" + HELPLINK + "\">" + HELPLINKCAPTION + "</a></li>\n" + " </ul>\n" + " </div></div>\n" + "</div></div>\n" + "</body>\n" + "</html>\n"); + + Template::Template() + { + m_showToggles = false; + } + + QCString Template::render(const SwordOptions& options) const + { + + QString cssdir = KGlobal::dirs()->findResourceDir("data", "kio_sword/kio_sword.css") + "kio_sword/"; + + QString output = html_page; + output = output + .replace(HOMELINK, swordUrl("", options)) + .replace(HOMELINKCAPTION, i18n("Module list")) + .replace(SEARCHLINK, swordUrlForPage("search", options)) + .replace(SEARCHLINKCAPTION, i18n("Search")) + .replace(SETTINGSLINK, swordUrlForSettings(m_currentPath, options)) + .replace(SETTINGSLINKCAPTION, i18n("Settings")) + .replace(HELPLINK, swordUrlForPage("help", options)) + .replace(HELPLINKCAPTION, i18n("Help")) + .replace(BASECSS, cssdir + "kio_sword.css") + .replace(PAGETITLE, m_title) + .replace(CONTENT, m_content); + if (!m_nav.isEmpty()) + { + output = output + .replace(TOPNAV, "<div class='navtop'><div class='inner'>" + m_nav + "</div></div>") + .replace(BOTTOMNAV, "<div class='navbottom'><div class='inner'>" + m_nav + "</div></div>"); + } + else + { + output = output + .replace(TOPNAV, "") + .replace(BOTTOMNAV, ""); + } + if (m_showToggles) + { + QString toggles; + SwordOptions toggledOptions(options); + + toggledOptions.verseNumbers.set(!toggledOptions.verseNumbers()); + toggles += "<li><a href=\"" + swordUrl(m_currentPath, toggledOptions) + "\" accesskey='v'>" + + i18n("Verse Numbers") + "</a></li>"; + toggledOptions.verseNumbers.set(!toggledOptions.verseNumbers()); + + toggledOptions.verseLineBreaks.set(!toggledOptions.verseLineBreaks()); + toggles += "<li><a href=\"" + swordUrl(m_currentPath, toggledOptions) + "\" accesskey='l'>" + + i18n("Verse Line Breaks") + "</a></li>"; + toggledOptions.verseLineBreaks.set(!toggledOptions.verseLineBreaks()); + + toggledOptions.strongs.set(!toggledOptions.strongs()); + toggles += "<li><a href=\"" + swordUrl(m_currentPath, toggledOptions) + "\" accesskey='s'>" + + i18n("Strongs") + "</a></li>"; + toggledOptions.strongs.set(!toggledOptions.strongs()); + + toggledOptions.morph.set(!toggledOptions.morph()); + toggles += "<li><a href=\"" + swordUrl(m_currentPath, toggledOptions) + "\" accesskey='m'>" + + i18n("Morphological tags") + "</a></li>"; + toggledOptions.morph.set(!toggledOptions.morph()); + + output = output.replace(TOGGLES, "<div class='toggles'><div class='inner'><ul>" + toggles + "</ul></div></div>"); + + } + else + { + output = output.replace(TOGGLES, ""); + } + return output.utf8(); + } + + void Template::setTitle(const QString& title) + { + m_title = title; + } + + void Template::setContent(const QString& content) + { + m_content = content; + } + + void Template::setNav(const QString& nav) + { + m_nav = nav; + } + + void Template::setCurrentPath(const QString& currentPath) + { + m_currentPath = currentPath; + } + + void Template::setShowToggles(bool showToggles) + { + m_showToggles = showToggles; + } +} + diff --git a/src/template.h b/src/template.h new file mode 100644 index 0000000..a803795 --- /dev/null +++ b/src/template.h @@ -0,0 +1,55 @@ +/*************************************************************************** + File: template.h + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef KS_TEMPLATE_H +#define KS_TEMPLATE_H + +#include <qstring.h> +#include <qcstring.h> + + +namespace KioSword { + + class SwordOptions; + + /** Template used to generate page to be returned */ + class Template { + private: + QString m_title; + QString m_content; + QString m_nav; + QString m_currentPath; + bool m_showToggles; + public: + Template(); + void setContent(const QString& content); + void setNav(const QString& nav); + void setTitle(const QString& title); + void setCurrentPath(const QString& currentPath); + void setShowToggles(bool showToggles); + QCString render(const SwordOptions& options) const; + + }; +} + +#endif diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 0000000..15e1506 --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1,212 @@ +/*************************************************************************** + File: utils.cpp + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + Description: Misc utility functions that don't belong anywhere else + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "utils.h" +#include "swordoptions.h" + +#include <kurl.h> +#include <qstring.h> + +namespace KioSword { + + const char* DEFBIBLE_STR = "bible"; + const char* GREEKSTRONGS_STR = "greekstrongs"; + const char* HEBREWSTRONGS_STR = "hebrewstrongs"; + const char* GREEKMORPH_STR = "greekmorph"; + const char* HEBREWMORPH_STR = "hebrewmorph"; + + const char* SWORD_PROTOCOL = "sword"; + + static void mergeOptionsToURL(KURL& url, const SwordOptions* options) + { + QMap<QString, QString> items = options->getQueryStringParams(); + QMap<QString, QString>::const_iterator it; + QMap<QString, QString>::const_iterator it_end = items.end(); + for(it = items.begin(); it != it_end; ++it) { + url.addQueryItem(it.key(), it.data()); + } + } + + static void mergeOptionsToURL(KURL& url, const SwordOptions& options) + { + return mergeOptionsToURL(url, &options); + } + + static QString htmlEncode(const QString& text) + { + QString output = text; + return output + .replace("&", "&") + .replace("<", "<") + .replace(">", ">") + .replace("\"", """); + } + + /** Returns options that need to be propagated as HTML for a form */ + QString optionsAsHiddenFields(const SwordOptions& options) + { + QString output; + QMap<QString, QString> items = options.getQueryStringParams(); + QMap<QString, QString>::const_iterator it; + QMap<QString, QString>::const_iterator it_end = items.end(); + for(it = items.begin(); it != it_end; ++it) { + output += QString("<input type=\"hidden\" name=\"%1\" value=\"%2\">") + .arg(it.key()) + .arg(htmlEncode(it.data())); + } + return output; + } + + /** + * return a valid sword URL to be used in anchors + * + * Many key names have spaces in them, and even trailing spaces + * which are stripped by Konqueror. We must encode them to + * ensure we can access them. + * + * @param path path to be encode + */ + QString swordUrl(const QString& path, const SwordOptions& options, bool htmlEncodeOutput) { + QString output; + KURL url; + url.setProtocol(SWORD_PROTOCOL); + if (path.at(0) != '/') + url.addPath("/"); + url.addPath(path); + mergeOptionsToURL(url, options); + if (htmlEncodeOutput) + return htmlEncode(url.url(0, 106)); // return as utf-8 + else + return url.url(0, 106); // return as utf-8 + } + + /** + * return a valid sword URL to be used in anchors + * + * @param module name of module + * @param reference within module + */ + QString swordUrl(const QString& module, const QString& ref, const SwordOptions& options, bool htmlEncodeOutput) { + if (ref.at(0) == '/') + return swordUrl(module + ref, options, htmlEncodeOutput); + else + return swordUrl(module + "/" + ref, options, htmlEncodeOutput); + } + + /** + * return a valid sword URL for 'pages' such as 'help', 'settings' etc, + * which are defined using a query parameter + */ + QString swordUrlForPage(const QString& page, const SwordOptions& options, bool htmlEncodeOutput) + { + QString output; + KURL url; + url.setProtocol(SWORD_PROTOCOL); + url.addPath("/"); + url.addQueryItem(page, ""); + mergeOptionsToURL(url, options); + if (htmlEncodeOutput) + return htmlEncode(url.url(0, 106)); // return as utf-8 + else + return url.url(0, 106); // return as utf-8 + } + + QString swordUrlForSettings(const QString& path, const SwordOptions& options, bool htmlEncodeOutput) + { + QString output; + KURL url; + url.setProtocol(SWORD_PROTOCOL); + url.addPath("/"); + url.addQueryItem("settings", ""); + + // Up to KDE 3.5.2 at least, there is a bug in KURL::url which + // doesn't take into account the encoding_hint for the query items, + // so we can't use addQueryItem for anything which has non-ascii chars + // url.addQueryItem("previouspath", path); + mergeOptionsToURL(url, options); + output = url.url(0, 106); // return as utf-8 + + // Add 'previouspath' manually + output += ( (url.queryItems().count() > 0) ? "&" : "?"); + output += "previouspath=" + KURL::encode_string(path, 106); + + if (htmlEncodeOutput) + return htmlEncode(output); + else + return output; + } + + /** Get a URL for doing a search */ + QString swordUrlForSearch(DefModuleType modType, const QString& searchQuery, const SwordOptions& options, bool htmlEncodeOutput) + { + return swordUrlForSearch(modType, searchQuery, &options, htmlEncodeOutput); + } + + /** Get a URL for doing a search */ + QString swordUrlForSearch(DefModuleType modType, const QString& searchQuery, const SwordOptions* options, bool htmlEncodeOutput) + { + QString modTypeStr; + QString output; + KURL url; + // FIXME - make this into a dictionary or something better? + switch (modType) + { + case DEFBIBLE: + modTypeStr = DEFBIBLE_STR; + break; + case GREEKSTRONGS: + modTypeStr = GREEKSTRONGS_STR; + break; + case HEBREWSTRONGS: + modTypeStr = HEBREWSTRONGS_STR; + break; + case GREEKMORPH: + modTypeStr = GREEKMORPH_STR; + break; + case HEBREWMORPH: + modTypeStr = HEBREWMORPH_STR; + break; + default: + return output; + } + url.setProtocol(SWORD_PROTOCOL); + url.addPath("/"); + url.addQueryItem("modtype", modTypeStr); + url.addQueryItem("query", searchQuery); + mergeOptionsToURL(url, options); + if (htmlEncodeOutput) + return htmlEncode(url.url(0, 106)); // return as utf-8 + else + return url.url(0, 106); // return as utf-8 + } + + /** truncate a string to len chars, adding an ellipsis if necessary */ + QString shorten(const QString &ref, uint len) { + QString output = ref.stripWhiteSpace(); + if (output.length() > len) + output = output.left(len-2) + "..."; + return output; + } + +} diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..b97124c --- /dev/null +++ b/src/utils.h @@ -0,0 +1,55 @@ +/*************************************************************************** + File: utils.h + Project: Kio-Sword -- An ioslave for SWORD and KDE + Copyright: Copyright (C) 2004-2005 Luke Plant + ***************************************************************************/ + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef UTILS_H +#define UTILS_H + +#include <qstring.h> +namespace KioSword { + + class SwordOptions; + + typedef enum { DEFMODULETYPE_NONE, + DEFBIBLE, + GREEKSTRONGS, + HEBREWSTRONGS, + GREEKMORPH, + HEBREWMORPH } DefModuleType; + + extern const char* DEFBIBLE_STR; + extern const char* GREEKSTRONGS_STR; + extern const char* HEBREWSTRONGS_STR; + extern const char* GREEKMORPH_STR; + extern const char* HEBREWMORPH_STR; + + QString optionsAsHiddenFields(const SwordOptions& options); + QString swordUrl(const QString& path, const SwordOptions& options, bool htmlEncodeOutput = true); + QString swordUrl(const QString& module, const QString& ref, const SwordOptions& options, bool htmlEncodeOutput = true); + QString swordUrlForPage(const QString& page, const SwordOptions& options, bool htmlEncodeOutput = true); + QString swordUrlForSettings(const QString& path, const SwordOptions& options, bool htmlEncodeOutput = true); + QString swordUrlForSearch(DefModuleType modType, const QString& searchQuery, const SwordOptions& options, bool htmlEncodeOutput = true); + QString swordUrlForSearch(DefModuleType modType, const QString& searchQuery, const SwordOptions* options, bool htmlEncodeOutput = true); + QString shorten(const QString& ref, uint len); + +} +#endif |