1 // -*- mode:C++ ; compile-command: "g++ -I.. -I../include -I../../giac/include -g -c Help1.cc" -*-
2 #include "Help1.h"
3 #include "Xcas1.h"
4 /*
5  *  Copyright (C) 2000,2014 B. Parisse, Institut Fourier, 38402 St Martin d'Heres
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #ifdef HAVE_LIBFLTK
26 #include <FL/fl_ask.H>
27 #include <FL/fl_ask.H>
28 #include <FL/Fl_Hold_Browser.H>
29 #include <fstream>
30 #include "vector.h"
31 #include <algorithm>
32 #include <fcntl.h>
33 #include <cmath>
34 #include <time.h> // for nanosleep
35 #include <stdio.h>
36 #include <dirent.h>
37 #include <sys/stat.h> // auto-recovery function
38 
39 using namespace std;
40 using namespace giac;
41 
42 #ifndef NO_NAMESPACE_XCAS
43 namespace xcas {
44 #endif // ndef NO_NAMESPACE_XCAS
45 
translate_html_title(const string & s)46   string translate_html_title(const string & s){
47     if (debug_infolevel)
48       cerr << s << endl;
49     int l=s.size();
50     string res;
51     for (int i=0;i<l;++i){
52       if (s[i]!='&'){
53 	switch(s[i]){
54 	case '\n':
55 	  res += ' ';
56 	  break;
57 	case '�': case '�': case '�':
58 	  res += 'e';
59 	  break;
60 	case '�':
61 	  res += 'a';
62 	  break;
63 	case '�':
64 	  res += 'o';
65 	  break;
66 	default:
67 	  res += s[i];
68 	}
69       }
70       else {
71 	int pos=s.find(';',i);
72 	if (pos>=l || pos<=i)
73 	  res +=s[i];
74 	else {
75 	  unsigned code=0,base=10;
76 	  char c;
77 	  for (int cur=i+2;cur<=pos;++cur){
78 	    c=s[cur];
79 	    if (c=='x' || c=='X')
80 	      base=16;
81 	    if (c=='o' || c=='O')
82 	      base=8;
83 	    if (c!=';'){
84 	      if (base!=16)
85 		code = code*base+c-'0';
86 	      else {
87 		if (c>='A' && c<='F')
88 		  code = code*base + c-'A'+10;
89 		if (c>='a' && c<='f')
90 		  code = code*base + c-'a'+10;
91 		if (c>='0' && c<='9')
92 		  code = code*base + c-'0';
93 	      }
94 	      continue;
95 	    }
96 	    switch (code){
97 	    case 0xe8: case 0xe9: case 0xea:
98 	      c='e';
99 	      break;
100 	    case 0xe0: case 0xe2:
101 	      c='a';
102 	      break;
103 	    case 0xf4:
104 	      c='o';
105 	      break;
106 	    case 0xf9: case 0xfb:
107 	      c='u';
108 	      break;
109 	    case 0xe7:
110 	      c='c';
111 	      break;
112 	    case 238:
113 	      c='i';
114 	      break;
115 	    case 0x2019:
116 	      c=' ';
117 	      break;
118 	    } // end switch
119 	    break;
120 	  } // end loop for (cur=i;cur<pos;++cur)
121 	  i=pos;
122 	  res += c;
123 	}
124       }
125     }
126     return res;
127   }
128 
help_translate(const string & s)129   string help_translate(const string & s){
130     int l=s.size();
131     string res;
132     for (int i=0;i<l;++i){
133       unsigned char c=s[i];
134       if (i<l-1 && c==0xc3){
135 	++i;
136 	c=s[i];
137 	switch (c){
138 	case 0xa8: case 0xa9: case 0xaa: case 0xab:
139 	  res += 'e';
140 	  break;
141 	case 0xa7:
142 	  res += 'c';
143 	  break;
144 	case 0xa0: case 0xa1: case 0xa2: case 0xa4:
145 	  res +='a';
146 	  break;
147 	case 0xb9: case 0xba: case 0xbb: case 0xbc:
148 	  res +='u';
149 	  break;
150 	case 0xb4: case 0xb5: case 0xb6:
151 	  res +='o';
152 	  break;
153 	case 0xae: case 0xaf:
154 	  res += 'i';
155 	  break;
156 	}
157 	continue;
158       }
159       switch (s[i]){
160 	case '�': case '�': case '�':
161 	  res += 'e';
162 	  break;
163 	case '�':
164 	  res += 'a';
165 	  break;
166 	case '�':
167 	  res += 'o';
168 	  break;
169 	  /*
170       case 'é':
171 	res += 'e'; // "&#233;";
172 	break;
173       case 'è':
174 	res +='e'; // "&#232;";
175 	break;
176       case 'ê':
177 	res += 'e'; // "&#234;";
178 	break;
179       case 'à':
180 	res += 'a'; // "&#224;";
181 	break;
182       case 'î':
183 	res += 'i'; // "&#238;";
184 	break;
185 	  */
186       default:
187 	res += tolower(s[i]);
188       }
189     }
190     return res;
191   }
192 
193   // help on topic s
help_fltk(const string & s_orig)194   void help_fltk(const string & s_orig){
195     static Fl_Window * w = 0;
196     static Fl_Button * button0 = 0;
197     static Fl_Button *button1 = 0;
198     static Fl_Hold_Browser * br = 0;
199     static Fl_Input * in=0;
200     static vector<string> v;
201     if (!w){
202 #ifdef IPAQ
203       int dx=230,dy=140,l=10;
204 #else
205       int dx=460,dy=260,l=20;
206 #endif
207       if (xcas::Xcas_input_focus && xcas::Xcas_input_focus->window()){
208 	dx=max(dx,2*xcas::Xcas_input_focus->window()->w()/3);
209 	dy=max(dy,2*xcas::Xcas_input_focus->window()->h()/3);
210 	l=xcas::Xcas_input_focus->window()->labelsize();
211       }
212       l += 6;
213       Fl_Group::current(0);
214       w = new Fl_Window(dx,dy);
215       w->label(gettext("Find word in HTML help"));
216       button0 = new Fl_Button(2,2,dx/2-4,l);
217       button1 = new Fl_Button(dx/2+2,2,dx/2-4,l);
218       in = new Fl_Input(dx/4,l+4,3*dx/4-2,l);
219       br = new Fl_Hold_Browser(2,2*l+6,dx-4,dy-2*l-8);
220       w->end();
221       l -= 6;
222       change_group_fontsize(w,l);
223       button0->shortcut("^[");
224       button1->label(gettext("Finish"));
225       button1->color(FL_ROUGE_PALE);
226       in->label(gettext("Searching for "));
227       in->when(FL_WHEN_ENTER_KEY|FL_WHEN_NOT_CHANGED);
228     }
229     if (!s_orig.empty()){
230       in->value(s_orig.c_str());
231       in->position(s_orig.size(),s_orig.size());
232     }
233     Fl::focus(in);
234     // Xcas->hide();
235     w->resizable(w);
236     w->set_modal();
237     w->show();
238     Fl::wait(0.0001);
239     int r=0;
240     for (;r!=1;){
241       button0->label(br->size()>0?gettext("View"):gettext("Find"));
242       button0->color(FL_VERT_PALE);
243       for (;;) {
244 	Fl_Widget *o = Fl::readqueue();
245 	if (!o) Fl::wait();
246 	else {
247 	  if (o == button0) { // view help file
248 	    int tmp=br->value();
249 	    if (tmp) {
250 	      if (use_external_browser)
251 		system_browser_command(v[tmp-1]);
252 	      else {
253 		use_external_browser=false;
254 		if (Xcas_help_window){
255 		  Xcas_help_window->load((v[tmp-1]).c_str());
256 		  xcas::Xcas_help_window->show();
257 		}
258 	      }
259 	    }
260 	    else {
261 	      if (!br->size())
262 		in->do_callback();
263 	      else
264 		fl_alert(gettext("Please select the title of the page"));
265 	    }
266 	  }
267 	  if (o == button1) {r = 1; break;}
268 	  if (o == w) { r=1; break; }
269 	  if (o==in) { break; }
270 	}
271       }
272       if (r==0){
273 	string s=help_translate(in->value());
274 	button0->label(gettext("Stop"));
275 	button0->color(FL_MAGENTA);
276 	br->clear();
277 	// fill browser
278 	//multimap<string,string>::const_iterator it=html_mtt.begin(),itend=html_mtt.end();
279 	v.clear();
280 	vector<string>::const_iterator it=html_vall.begin(),itend=html_vall.end();
281 	for (;it!=itend;++it){
282 	  Fl_Widget *o = Fl::readqueue();
283 	  if (o){
284 	    if (o==button0) {break;}
285 	    if (o==button1 || o==w){ r=1; break; }
286 	  }
287 	  else {
288 	    if ( ! ((itend-it)%10) )
289 	      Fl::wait(0.0001);
290 	  }
291 	  //string fname(absolute_path(it->second));
292 	  string fname(absolute_path(*it));
293 	  // remove #... part at the end of the URL
294 	  int lf=fname.size()-1;
295 	  for (;lf>0;--lf){
296 	    if (fname[lf]=='#'){
297 	      fname=fname.substr(0,lf);
298 	      break;
299 	    }
300 	  }
301 	  if (grep(fname,s)){
302 	    FILE * f=fopen(fname.c_str(),"r");
303 	    if (f && grep(f,"<TITLE>")){
304 	      string title;
305 	      for (;!feof(f) && !ferror(f);){
306 		char c=fgetc(f);
307 		if (feof(f) || c=='<')
308 		  break;
309 		title += c;
310 	      }
311 	      fclose(f);
312 	      br->add(translate_html_title(title).c_str());
313 	      //v.push_back(it->second);
314 	      v.push_back(*it);
315 	      br->redraw();
316 	    }
317 	  }
318 	} // end for (;it!=itend;)
319       } // end if (r==0)
320     } // end for (;;)
321     w->hide();
322   }
323 
324 
325 
326 
327 #ifndef NO_NAMESPACE_XCAS
328 } // namespace giac
329 #endif // ndef NO_NAMESPACE_XCAS
330 
331 #endif // HAVE_LIBFLTK
332