lib

kohyphen.cpp
1/******************************************************************************
2 * Copyright (C) 2002 by Alexander Dymo <cloudtemple@mskat.net> *
3 * Copyright (C) 2002-2003 by Lukas Tinkl <lukas@kde.org> *
4 * Copyright (C) 2003 David Faure <faure@kde.org> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU Library General Public License as *
8 * published by the Free Software Foundation; either version 2 of the *
9 * License, or (at your option) any later version. *
10 * *
11 * This library is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * Library General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU Library General Public License *
17 * along with this library; see the file COPYING.LIB. If not, write to *
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA. *
20 ******************************************************************************/
21
22#include <tqdom.h>
23#include <tqfile.h>
24#include <tqtextcodec.h>
25#include <tqstring.h>
26
27#include <tdelocale.h>
28#include <tdeapplication.h>
29#include <kstandarddirs.h>
30#include <kstaticdeleter.h>
31
32#include "kohyphen.h"
33#include <kdebug.h>
34
35
36//#define DEBUG_HYPHENATOR 1
37
38KoHyphenator* KoHyphenator::s_self;
39static KStaticDeleter<KoHyphenator> kohyphensd;
40
41KoHyphenator* KoHyphenator::self()
42{
43 if ( !s_self )
44 kohyphensd.setObject( s_self, new KoHyphenator );
45 return s_self;
46}
47
48KoHyphenator::KoHyphenator()
49{
50/* Reading config for dictionary encodings from file...*/
51
52 TQString path = kapp->dirs()->findResource("data", "koffice/hyphdicts/dicts.xml");
53#ifdef DEBUG_HYPHENATOR
54 kdDebug() << path << endl;
55#endif
56
57 TQFile *f;
58 if (!path.isNull())
59 f = new TQFile(path);
60 else
61 throw KoHyphenatorException( "Could not create KoHyphenator instance." );
62
63 TQDomDocument config;
64 TQDomNodeList records;
65 config.setContent(f);
66
67 for (TQDomNode n = config.firstChild(); !n.isNull(); n = n.nextSibling())
68 if (n.nodeName() == "dicts")
69 {
70 records = n.childNodes();
71 for (uint i = 0; i < records.count(); i++)
72 {
73 TQDomNamedNodeMap attr = records.item(i).attributes();
74 if (attr.contains("lang") && attr.contains("encoding")) {
75 TQString lang = attr.namedItem("lang").nodeValue();
76 TQString encoding = attr.namedItem("encoding").nodeValue();
77#ifdef DEBUG_HYPHENATOR
78 kdDebug() << "KoHyphenator: found lang=" << lang << " encoding=" << encoding << endl;
79#endif
80 encodings.insert( lang,
81 EncodingStruct( encoding.latin1() ) );
82 }
83 }
84 }
85
86 delete f;
87}
88
89KoHyphenator::~KoHyphenator()
90{
91 for (TQMap<TQString, HyphenDict*>::iterator it = dicts.begin(); it != dicts.end(); ++it)
92 {
93 if ((*it) != 0)
94 hnj_hyphen_free((*it));
95 }
96}
97
98char *KoHyphenator::hyphens(const TQString& str, const TQString& lang) const
99{
100 char *x = new char[str.length()+1];
101 try
102 {
103 TQTextCodec *codec = codecForLang(lang);
104 hnj_hyphen_hyphenate(dict(lang), (const char *)(codec->fromUnicode(str)), str.length(), x);
105 }
106 catch (KoHyphenatorException &e)
107 {
108#ifdef DEBUG_HYPHENATOR
109 kdDebug() << e.message().latin1() << endl;
110#endif
111 for (uint j = 0; j < str.length(); j++)
112 x[j] = '0';
113 x[str.length()] = '\0';
114 }
115 return x;
116}
117
118TQString KoHyphenator::hyphenate(const TQString& str, const TQString& lang) const
119{
120 char* x = new char[str.length()+1];
121 TQString res = str;
122 try
123 {
124 TQTextCodec *codec = codecForLang(lang);
125 hnj_hyphen_hyphenate(dict(lang), (const char *)(codec->fromUnicode(str)), str.length(), x);
126 }
127 catch (KoHyphenatorException &e)
128 {
129#ifdef DEBUG_HYPHENATOR
130 kdDebug() << e.message() << endl;
131#endif
132 delete[] x;
133 return str;
134 }
135 int i = 0, j = 0;
136 int len = strlen(x);
137 for (; i < len; i++)
138 {
139#ifdef DEBUG_HYPHENATOR
140 kdDebug() << "loop: i=" << i << ", j=" << j << ", x=" << x << ", res=" << res << endl;
141#endif
142 if ((x[i] % 2) != 0)
143 {
144 res.insert(j+1, TQChar(0xad));
145 j++;
146 }
147 j++;
148 }
149 delete[] x;
150 return res;
151}
152
153bool KoHyphenator::checkHyphenPos(const TQString& str, int pos, const TQString& lang) const
154{
155#ifdef DEBUG_HYPHENATOR
156 kdDebug() << "string: " << str << endl;
157#endif
158
159 char *hyph = hyphens(str, lang);
160
161#ifdef DEBUG_HYPHENATOR
162 kdDebug() << "result: " << hyph << endl;
163 kdDebug() << "checked position: " << pos << endl;
164#endif
165 bool ret = ((hyph[pos] % 2) != 0);
166 delete[] hyph;
167 return ret;
168}
169
170HyphenDict *KoHyphenator::dict(const TQString &_lang) const
171{
172 TQString lang( _lang );
173 //only load dictionary when encoding info is present
174 if (encodings.find(lang) == encodings.end())
175 {
176 int underscore = lang.find('_');
177 if ( underscore > -1 ) {
178 lang.truncate( underscore );
179 if (encodings.find(lang) == encodings.end())
180 throw KoHyphenatorException( TQString("No dictionary for %1").arg(lang) );
181 }
182 else
183 throw KoHyphenatorException( TQString("No dictionary for %1").arg(lang) );
184 }
185 if (dicts.find(lang) == dicts.end())
186 {
187#ifdef DEBUG_HYPHENATOR
188 kdDebug() << "Searching dictionary for '" << lang << "' language..." << endl;
189#endif
190 TQString path = kapp->dirs()->findResource("data", "koffice/hyphdicts/hyph_" + lang + ".dic");
191 if (!path.isNull())
192 {
193#ifdef DEBUG_HYPHENATOR
194 kdDebug() << "Loading dictionary for '" << lang << "' language: path = " << path << endl;
195#endif
196 const_cast<KoHyphenator*>(this)->dicts.insert( lang, hnj_hyphen_load(TQFile::encodeName(path)) );
197 if (dicts.find(lang) == dicts.end())
198 {
199#ifdef DEBUG_HYPHENATOR
200 kdDebug() << "No dictionary loaded" << endl;
201#endif
202 throw(KoHyphenatorException( TQString("Could not load dictionary for the language: %1").arg(lang) ));
203 }
204 }
205 else
206 throw(KoHyphenatorException( TQString("Could not load dictionary for the language: %1").arg(lang) ));
207 }
208 return dicts[lang];
209}
210
211TQTextCodec* KoHyphenator::codecForLang(const TQString& lang) const
212{
213 EncodingMap::Iterator it = encodings.find(lang);
214 if (it == encodings.end())
215 {
216 int underscore = lang.find('_');
217 if ( underscore > -1 ) {
218 TQString _lang( lang );
219 _lang.truncate( underscore );
220 it = encodings.find(_lang);
221 }
222 }
223 if (it != encodings.end())
224 {
225 if ( (*it).codec )
226 return (*it).codec;
227 (*it).codec = TQTextCodec::codecForName((*it).encoding);
228 return (*it).codec;
229 }
230 return TQTextCodec::codecForMib(106); // utf-8
231}
The KoHyphenator class provides an interface to the libhnj hyphenation library.
Definition kohyphen.h:56
bool checkHyphenPos(const TQString &str, int pos, const TQString &lang) const
Checks if the letter in position pos is placed before the hyphen.
Definition kohyphen.cpp:153
static KoHyphenator * self()
Returns the single KoHyphenator instance (singleton pattern) Beware that this might throw an exceptio...
Definition kohyphen.cpp:41
char * hyphens(const TQString &str, const TQString &lang) const
Returns the pointer to the string in hnj_hyphen_hyphenate() format (that is hyphenation function from...
Definition kohyphen.cpp:98
TQString hyphenate(const TQString &str, const TQString &lang) const
Hyphenates the string str and returns the string with hyphenation marks in it.
Definition kohyphen.cpp:118