summaryrefslogtreecommitdiff
path: root/src/backend/filters/teitohtml.cpp
blob: 4b390d51622c0cd1cbf7fb963799b7d5ecffb280 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*********
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
* Copyright 1999-2011 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/

#include "backend/filters/teitohtml.h"

#include <QString>
#include "backend/config/cbtconfig.h"
#include "backend/drivers/cswordmoduleinfo.h"
#include "backend/managers/clanguagemgr.h"
#include "backend/managers/referencemanager.h"

// Sword includes:
#include <swbuf.h>
#include <swmodule.h>
#include <utilxml.h>


namespace Filters {

TeiToHtml::TeiToHtml()
    : sword::TEIHTMLHREF()
{
    setPassThruUnknownEscapeString(true); // the HTML widget will render the HTML escape codes
}

bool TeiToHtml::handleToken(sword::SWBuf &buf, const char *token,
                            sword::BasicFilterUserData *userData)
{
    // manually process if it wasn't a simple substitution

    if (!substituteToken(buf, token)) {

        sword::XMLTag tag(token);

        if (0) {

        }
        else if (!strcmp(tag.getName(), "ref")) {

            if (!tag.isEndTag() && !tag.isEmpty()) {

                renderReference(tag.getAttribute("osisRef"), buf, userData);

            }
            else if (tag.isEndTag()) {
                buf.append("</a>");
            }
            else { // empty reference marker
                // -- what should we do?  nothing for now.
            }
        }
        // <hi> highlighted text
        else if (!strcmp(tag.getName(), "hi")) {
            const sword::SWBuf type = tag.getAttribute("rend");

            if ((!tag.isEndTag()) && (!tag.isEmpty())) {
                if (type == "bold") {
                    buf.append("<span class=\"bold\">");
                }
                else if (type == "illuminated") {
                    buf.append("<span class=\"illuminated\">");
                }
                else if (type == "italic") {
                    buf.append("<span class=\"italic\">");
                }
                else if (type == "line-through") {
                    buf.append("<span class=\"line-through\">");
                }
                else if (type == "normal") {
                    buf.append("<span class=\"normal\">");
                }
                else if (type == "small-caps") {
                    buf.append("<span class=\"small-caps\">");
                }
                else if (type == "underline") {
                    buf.append("<span class=\"underline\">");
                }
                else {
                    buf.append("<span>"); //don't break markup, </span> is inserted later
                }
            }
            else if (tag.isEndTag()) { //all hi replacements are html spans
                buf.append("</span>");
            }
        }
        else { //all tokens handled by OSISHTMLHref will run through the filter now
            return sword::TEIHTMLHREF::handleToken(buf, token, userData);
        }
    }

    return false;
}

void TeiToHtml::renderReference(const char *osisRef, sword::SWBuf &buf,
                                sword::BasicFilterUserData *myUserData)
{
    QString ref( osisRef );
    QString hrefRef( ref );

    if (!ref.isEmpty()) {
        //find out the mod, using the current module makes sense if it's a bible or commentary because the refs link into a bible by default.
        //If the osisRef is something like "ModuleID:key comes here" then the
        // modulename is given, so we'll use that one

        CSwordModuleInfo* mod = CBTConfig::get( CBTConfig::standardBible );

        // Q_ASSERT(mod); There's no necessarily a module or standard Bible

        //if the osisRef like "GerLut:key" contains a module, use that
        int pos = ref.indexOf(":");

        if ((pos >= 0) && ref.at(pos - 1).isLetter() && ref.at(pos + 1).isLetter()) {
            QString newModuleName = ref.left(pos);
            hrefRef = ref.mid(pos + 1);

            if (CSwordBackend::instance()->findModuleByName(newModuleName)) {
                mod = CSwordBackend::instance()->findModuleByName(newModuleName);
            }
        }

        if (mod) {
            ReferenceManager::ParseOptions options;
            options.refBase = QString::fromUtf8(myUserData->key->getText());
            options.refDestinationModule = QString(mod->name());
            options.sourceLanguage = QString(mod->module()->Lang());
            options.destinationLanguage = QString("en");

            buf.append("<a href=\"");
            buf.append( //create the hyperlink with key and mod
                ReferenceManager::encodeHyperlink(
                    mod->name(),
                    ReferenceManager::parseVerseReference(hrefRef, options),
                    ReferenceManager::typeFromModule(mod->type())
                ).toUtf8().constData()
            );
            buf.append("\" crossrefs=\"");
            buf.append((const char*)ReferenceManager::parseVerseReference(ref, options).toUtf8().constData()); //ref must contain the osisRef module marker if there was any
            buf.append("\">");
        }
        // should we add something if there were no referenced module available?
    }
}

} // namespace Filters