summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am21
-rw-r--r--src/data/Makefile.am4
-rw-r--r--src/data/kio_sword.css273
-rw-r--r--src/data/kio_sword.css.in273
-rw-r--r--src/data/swordvertical.pngbin0 -> 5729 bytes
-rw-r--r--src/filter.cpp35
-rw-r--r--src/filter.h39
-rw-r--r--src/kio_sword.cpp676
-rw-r--r--src/kio_sword.h93
-rw-r--r--src/kio_sword.lsm16
-rw-r--r--src/ks_gbfhtml.cpp236
-rw-r--r--src/ks_gbfhtml.h54
-rw-r--r--src/ks_osishtml.cpp358
-rw-r--r--src/ks_osishtml.h60
-rw-r--r--src/ks_thmlhtml.cpp222
-rw-r--r--src/ks_thmlhtml.h58
-rw-r--r--src/option.h300
-rw-r--r--src/pics/Makefile.am11
-rw-r--r--src/pics/hi128-app-kio_sword.pngbin0 -> 10530 bytes
-rw-r--r--src/pics/hi16-app-kio_sword.pngbin0 -> 679 bytes
-rw-r--r--src/pics/hi22-app-kio_sword.pngbin0 -> 1011 bytes
-rw-r--r--src/pics/hi32-app-kio_sword.pngbin0 -> 1623 bytes
-rw-r--r--src/pics/hi48-app-kio_sword.pngbin0 -> 2785 bytes
-rw-r--r--src/pics/hi64-app-kio_sword.pngbin0 -> 4126 bytes
-rw-r--r--src/pics/hisc-app-kio_sword.svgzbin0 -> 4942 bytes
-rw-r--r--src/pics/kio_sword_borders.xcfbin0 -> 55976 bytes
-rw-r--r--src/pics/kio_sword_everything.svg1879
-rw-r--r--src/renderer.cpp1028
-rw-r--r--src/renderer.h131
-rw-r--r--src/sword.protocol13
-rw-r--r--src/swordoptions.cpp174
-rw-r--r--src/swordoptions.h100
-rw-r--r--src/swordutils.cpp86
-rw-r--r--src/swordutils.h35
-rw-r--r--src/template.cpp175
-rw-r--r--src/template.h55
-rw-r--r--src/utils.cpp212
-rw-r--r--src/utils.h55
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
new file mode 100644
index 0000000..9254aaa
--- /dev/null
+++ b/src/data/swordvertical.png
Binary files differ
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 &nbsp;&nbsp;<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'>&nbsp;" // "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 *
+ * *
+ * 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'>&lt;<a href=\"";
+ buf += swordUrlForSearch(GREEKSTRONGS, val, m_swordoptions).utf8();
+ buf += "\">";
+ for (tok = (!isdigit(*val))?val+1:val; *tok; tok++)
+ buf += *tok;
+ buf += "</a>&gt;</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'>&lt;<a href=\"";
+ buf += swordUrlForSearch(GREEKSTRONGS, token + 2, m_swordoptions).utf8();
+ buf += "\">";
+ for (tok = token + 2; *tok; tok++)
+ //if(token[i] != '\"')
+ buf += *tok;
+ buf += "</a>&gt;</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 += "&nbsp<a href=\"note=";
+ buf += u->lastTextNode.c_str();
+ buf += "\">";
+ buf += "<small><sup>*n</sup></small></a>&nbsp";
+ // 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'>&lt;<a href=\"%2\">%1</a>&gt;</span> ")
+ .arg(val+1)
+ .arg(swordUrlForSearch(GREEKSTRONGS, val+1, m_swordoptions))
+ .utf8());
+ } else if (*val == 'H') {
+ buf.append(QString(" <span class='strongs'>&lt;<a href=\"%2\">%1</a>&gt;</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'>&lt;%s&gt;</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'>&lt;<a href=\"%2\">%1</a>&gt;</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'>&lt;<a href=\"%2\">%1</a>&gt;</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
new file mode 100644
index 0000000..dc3f665
--- /dev/null
+++ b/src/pics/hi128-app-kio_sword.png
Binary files differ
diff --git a/src/pics/hi16-app-kio_sword.png b/src/pics/hi16-app-kio_sword.png
new file mode 100644
index 0000000..6897bdc
--- /dev/null
+++ b/src/pics/hi16-app-kio_sword.png
Binary files differ
diff --git a/src/pics/hi22-app-kio_sword.png b/src/pics/hi22-app-kio_sword.png
new file mode 100644
index 0000000..c4da37d
--- /dev/null
+++ b/src/pics/hi22-app-kio_sword.png
Binary files differ
diff --git a/src/pics/hi32-app-kio_sword.png b/src/pics/hi32-app-kio_sword.png
new file mode 100644
index 0000000..63db51d
--- /dev/null
+++ b/src/pics/hi32-app-kio_sword.png
Binary files differ
diff --git a/src/pics/hi48-app-kio_sword.png b/src/pics/hi48-app-kio_sword.png
new file mode 100644
index 0000000..2175625
--- /dev/null
+++ b/src/pics/hi48-app-kio_sword.png
Binary files differ
diff --git a/src/pics/hi64-app-kio_sword.png b/src/pics/hi64-app-kio_sword.png
new file mode 100644
index 0000000..cf970ff
--- /dev/null
+++ b/src/pics/hi64-app-kio_sword.png
Binary files differ
diff --git a/src/pics/hisc-app-kio_sword.svgz b/src/pics/hisc-app-kio_sword.svgz
new file mode 100644
index 0000000..fff5113
--- /dev/null
+++ b/src/pics/hisc-app-kio_sword.svgz
Binary files differ
diff --git a/src/pics/kio_sword_borders.xcf b/src/pics/kio_sword_borders.xcf
new file mode 100644
index 0000000..5756d2b
--- /dev/null
+++ b/src/pics/kio_sword_borders.xcf
Binary files differ
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\">&laquo %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 &raquo</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("&", "&amp;")
+ .replace("<", "&lt;")
+ .replace(">", "&gt;")
+ .replace("\"", "&quot;");
+ }
+
+ /** 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