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'; // "é"; 172 break; 173 case 'è': 174 res +='e'; // "è"; 175 break; 176 case 'ê': 177 res += 'e'; // "ê"; 178 break; 179 case 'à': 180 res += 'a'; // "à"; 181 break; 182 case 'î': 183 res += 'i'; // "î"; 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