~registry/texmacs/trunk

« back to all changes in this revision

Viewing changes to src/src/Plugins/Ispell/ispell.cpp

  • Committer: mgubi
  • Date: 2009-06-04 15:13:41 UTC
  • Revision ID: svn-v4:64cb5145-927a-446d-8aed-2fb7b4773692:trunk:2717
Support for X11 TeXmacs.app on Mac

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/******************************************************************************
3
 
* MODULE     : ispell.cpp
4
 
* DESCRIPTION: interface with the ispell spell checker
5
 
* COPYRIGHT  : (C) 1999  Joris van der Hoeven
6
 
*******************************************************************************
7
 
* This software falls under the GNU general public license version 3 or later.
8
 
* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9
 
* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10
 
******************************************************************************/
11
 
 
12
 
#include "Ispell/ispell.hpp"
13
 
#include "file.hpp"
14
 
#include "resource.hpp"
15
 
#include "tm_link.hpp"
16
 
#include "convert.hpp"
17
 
 
18
 
string ispell_dictionary (string lang);
19
 
string ispell_extra_args (string lang);
20
 
string ispell_encode (string lan, string s);
21
 
string ispell_decode (string lan, string s);
22
 
 
23
 
/******************************************************************************
24
 
* The connection resource
25
 
******************************************************************************/
26
 
 
27
 
RESOURCE(ispeller);
28
 
struct ispeller_rep: rep<ispeller> {
29
 
  string  lan; // name of the session
30
 
  tm_link ln;  // the pipe
31
 
 
32
 
public:
33
 
  ispeller_rep (string lan);
34
 
  string start ();
35
 
  string retrieve ();
36
 
  void   send (string cmd);
37
 
};
38
 
RESOURCE_CODE(ispeller);
39
 
 
40
 
/******************************************************************************
41
 
* Routines for ispellers
42
 
******************************************************************************/
43
 
 
44
 
ispeller_rep::ispeller_rep (string lan2): rep<ispeller> (lan2), lan (lan2) {}
45
 
 
46
 
string
47
 
ispeller_rep::start () {
48
 
  if (is_nil (ln)) {
49
 
#ifdef OS_WIN32
50
 
    string prg= "\"$TEXMACS_PATH/bin/aspell/aspell.exe\"";
51
 
    string cmd= prg * " --data-dir=.%//data --dict-dir=.%//dict -a";
52
 
#else
53
 
    string cmd= "ispell -a -d " * ispell_dictionary (lan)
54
 
      * ispell_extra_args (lan);
55
 
    if (exists_in_path ("aspell")) cmd[0]= 'a';
56
 
#endif
57
 
    ln= make_pipe_link (cmd);
58
 
  }
59
 
  if (ln->alive) return "ok";
60
 
  string message= ln->start ();
61
 
  if (starts (message, "Error: ")) return message;
62
 
  message= retrieve ();
63
 
#ifdef OS_WIN32
64
 
  if (search_forwards (message, 0, "@(#)")) return "ok";
65
 
#else
66
 
  if (starts (message, "@(#)")) return "ok";
67
 
#endif
68
 
  return "Error: no dictionary for#" * lan;
69
 
}
70
 
 
71
 
string
72
 
ispeller_rep::retrieve () {
73
 
  string ret;
74
 
  while ((ret != "\n") && (!ends (ret, "\n\n")) &&
75
 
         ((!ends (ret, "\n")) || (!starts (ret, "@(#)"))))
76
 
    {
77
 
      ln->listen (10000);
78
 
      string mess = ln->read (LINK_ERR);
79
 
      string extra= ln->read (LINK_OUT);
80
 
      if (mess  != "") cerr << "TeXmacs] ispell error: " << mess << "\n";
81
 
      if (extra == "") return "Error: ispell does not respond";
82
 
      ret << extra;
83
 
    }
84
 
  return ispell_decode(lan,ret);
85
 
}
86
 
 
87
 
void
88
 
ispeller_rep::send (string cmd) {
89
 
  ln->write (ispell_encode(lan,cmd) * "\n", LINK_IN);
90
 
}
91
 
 
92
 
/******************************************************************************
93
 
* Ispell dictionaries
94
 
******************************************************************************/
95
 
 
96
 
static hashmap<string,string> the_dict ("");
97
 
 
98
 
static void
99
 
init_dictionary (string lang, string dict) {
100
 
  if (the_dict->contains (lang)) return;
101
 
  if (exists ("/usr/lib/ispell/" * dict * ".hash") ||
102
 
      exists ("/usr/lib/aspell/" * dict) ||
103
 
      exists ("/usr/lib/aspell/" * dict * ".multi"))
104
 
    the_dict (lang)= dict;
105
 
}
106
 
 
107
 
string
108
 
ispell_dictionary (string lang) {
109
 
  if (N(the_dict) == 0) {
110
 
    init_dictionary ("english", "english");
111
 
    init_dictionary ("english", "american");
112
 
    init_dictionary ("danish", "danish");
113
 
    init_dictionary ("danish", "dansk");
114
 
    init_dictionary ("dutch", "dutch");
115
 
    init_dictionary ("dutch", "nederlands");
116
 
    init_dictionary ("french", "french");
117
 
    init_dictionary ("french", "francais");
118
 
    init_dictionary ("german", "german");
119
 
    init_dictionary ("german", "deutsch");
120
 
    init_dictionary ("german", "ngerman");
121
 
    init_dictionary ("german", "ndeutsch");
122
 
    init_dictionary ("german", "ogerman");
123
 
    init_dictionary ("german", "odeutsch");
124
 
    init_dictionary ("german", "swiss");
125
 
    init_dictionary ("portuguese", "portuguese");
126
 
    init_dictionary ("portuguese", "portugues");
127
 
    init_dictionary ("portuguese", "brazilian");
128
 
    init_dictionary ("portuguese", "brasileiro");
129
 
    init_dictionary ("spanish", "spanish");
130
 
    init_dictionary ("spanish", "español");
131
 
    init_dictionary ("spanish", "espa~nol");
132
 
    init_dictionary ("spanish", "espanol");
133
 
    init_dictionary ("spanish", "castellano");
134
 
    init_dictionary ("swedish", "swedish");
135
 
    init_dictionary ("swedish", "svenska");
136
 
  }
137
 
  if (the_dict->contains (lang)) return the_dict [lang];
138
 
  return lang;
139
 
}
140
 
 
141
 
/******************************************************************************
142
 
* Language dependent arguments to ispell
143
 
******************************************************************************/
144
 
 
145
 
string
146
 
ispell_extra_args (string lan) {
147
 
  if (lan == "german")
148
 
    return " -T latin1";
149
 
  else
150
 
    return "";
151
 
}
152
 
 
153
 
/******************************************************************************
154
 
* Internationalization
155
 
******************************************************************************/
156
 
 
157
 
string
158
 
ispell_encode (string lan, string s) {
159
 
  if ((lan == "czech") || (lan == "hungarian") ||
160
 
      (lan == "polish") || (lan == "slovene"))
161
 
    return cork_to_il2 (s);
162
 
  else if ((lan == "bulgarian") || (lan == "russian"))
163
 
    return koi8_to_iso (s);
164
 
  else if (lan == "ukrainian")
165
 
    return koi8uk_to_iso (s);
166
 
  else if (lan == "spanish")
167
 
    return spanish_to_ispanish (s);
168
 
  else if (lan == "german")
169
 
    return german_to_igerman (s);
170
 
  else return s;
171
 
}
172
 
 
173
 
string
174
 
ispell_decode (string lan, string s) {
175
 
  if ((lan == "czech") || (lan == "hungarian") ||
176
 
      (lan == "polish") || (lan == "slovene"))
177
 
    return il2_to_cork (s);
178
 
  else if ((lan == "bulgarian") || (lan == "russian"))
179
 
    return iso_to_koi8 (s);
180
 
  else if (lan == "ukrainian")
181
 
    return iso_to_koi8uk (s);
182
 
  else if (lan == "spanish")
183
 
    return ispanish_to_spanish (s);
184
 
  else if (lan == "german")
185
 
    return igerman_to_german (s);
186
 
  else return s;
187
 
}
188
 
 
189
 
/******************************************************************************
190
 
* Subroutines
191
 
******************************************************************************/
192
 
 
193
 
static tree
194
 
parse_ispell (string s) {
195
 
  while (ends (s, "\n")) s= s (0, N(s)-1);
196
 
  bool flag= true;
197
 
  int i, j;
198
 
  tree t (TUPLE);
199
 
  for (i=0, j=0; j<N(s); j++)
200
 
    if (s[j]==':') flag= false;
201
 
    else if (((s[j]==' ') && (flag || (j==i) || (s[j-1]==':'))) || (s[j]==','))
202
 
      {
203
 
        if (j>i) t << s (i, j);
204
 
        i= j+1;
205
 
      }
206
 
  t << s (i, j);
207
 
 
208
 
  if (N(t) == 0) return tree (TUPLE, "0");
209
 
  if ((t[0] == "+") || (t[0] == "*") || (t[0] == "-")) return "ok";
210
 
  if ((N(t)>=4) && ((t[0] == "&") || (t[0]=="?"))) {
211
 
    tree u (TUPLE, t[2]);
212
 
    u << A (t (4, N (t)));
213
 
    return u;
214
 
  }
215
 
  return tree (TUPLE, "0");
216
 
}
217
 
 
218
 
static void
219
 
ispell_send (string lan, string s) {
220
 
  ispeller sc= ispeller (lan);
221
 
  if ((!is_nil (sc)) && sc->ln->alive) sc->send (s);
222
 
}
223
 
 
224
 
static string
225
 
ispell_eval (string lan, string s) {
226
 
  ispeller sc= ispeller (lan);
227
 
  if ((!is_nil (sc)) && sc->ln->alive) {
228
 
    sc->send (s);
229
 
    return sc->retrieve ();
230
 
  }
231
 
  return "";
232
 
}
233
 
 
234
 
/******************************************************************************
235
 
* Spell checking interface
236
 
******************************************************************************/
237
 
 
238
 
string
239
 
ispell_start (string lan) {
240
 
  ispeller sc= ispeller (lan);
241
 
  if (is_nil (sc)) sc= tm_new<ispeller_rep> (lan);
242
 
  return sc->start ();
243
 
}
244
 
 
245
 
tree
246
 
ispell_check (string lan, string s) {
247
 
  ispeller sc= ispeller (lan);
248
 
  if (is_nil (sc) || (!sc->ln->alive)) {
249
 
    string message= ispell_start (lan);
250
 
    if (starts (message, "Error: ")) return message;
251
 
  }
252
 
  string ret_s= ispell_eval (lan, "^" * s);
253
 
  if (starts (ret_s, "Error: ")) return ret_s;
254
 
  return parse_ispell (ret_s);
255
 
}
256
 
 
257
 
void
258
 
ispell_accept (string lan, string s) {
259
 
  ispell_send (lan, "@" * s);
260
 
}
261
 
 
262
 
void
263
 
ispell_insert (string lan, string s) {
264
 
  ispell_send (lan, "*" * s);
265
 
}
266
 
 
267
 
void
268
 
ispell_done (string lan) {
269
 
  ispell_send (lan, "#");
270
 
}