1
2
3
4 """
5 Management of the documentation of mathbench and its plugins.
6 """
7
8 import os
9 import logging
10 import re
11
12 import wx.py.dispatcher as dispatcher
13
15 """
16 Defang html symbols.
17
18 Inspired from :
19 http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
20 """
21 symbol_dict = {
22 "&" : "&",
23 ">" : ">",
24 "<" : "<",
25 "é" : "é",
26 "è" : "è",
27 "à" : "à",
28 "\n" : " \n<br>",
29 }
30 re_match_pattern = "(%s)" % "|".join( map(re.escape, symbol_dict.keys()) )
31 return re.sub( re_match_pattern, lambda m:symbol_dict[m.group()], txt )
32
33
35 """
36 A simple search engine to index the documentation of MathBench's
37 basic usages.
38 """
39
40 MATHBENCH_WEBSITE = "http://mathbench.sourceforge.net/"
41
43 """
44 Create the indexing dictionary
45 """
46
47
48
49 self.search_dict = {
50 "mathbench help shell idea completion python test idea" :
51 ( self.MATHBENCH_WEBSITE + "doc-basic-usage.html",
52 "Basic usage of the shell"),
53
54 "mathbench help editor execute execution python refine work" :
55 ( self.MATHBENCH_WEBSITE + "doc-editor-work.html",
56 "Working with the editor"),
57
58 "mathbench help librarydesk documentation search query" :
59 ( self.MATHBENCH_WEBSITE + "doc-library-use.html",
60 "Search the documentation via the library desk"),
61
62 "mathbench help extend plugin install" :
63 ( self.MATHBENCH_WEBSITE + "doc-plugins.html",
64 "Adapt the application to your needs with plugins"),
65 }
66
67
68 - def search(self,search_query):
69 """
70 Search the documentation
71 """
72
73 search_query_kw = search_query.split()
74
75 result_dict = {}
76 for key in self.search_dict.keys():
77 count = 0
78 for item in search_query_kw:
79 if key.find(str(item))!=-1:
80 count += 1
81 if count != 0:
82 if result_dict.has_key(count):
83 result_dict[count].append(self.search_dict[key])
84 else:
85 result_dict[count] = [self.search_dict[key]]
86
87 ranks = result_dict.keys()
88 ranks.sort()
89 ranks.reverse()
90 results = []
91 for r in ranks:
92 results.extend(result_dict[r])
93
94 return results
95
96
98 """
99 A singleton class in charge of building, updating the library
100 and also performing the searches.
101
102 The librarian is in charge of creating the library desk display
103 and then must be informed of which DeskFacory to use to create
104 this desk.
105
106 The display widget created must also send a 'LibraryDeskClosed'
107 signal when it is closed.
108 """
109
110 __instance = None
111
113 """
114 Initialisation: this class should not be initialised
115 explicitly and the ``get`` classmethod must be called instead.
116 """
117 if self.__instance is not None:
118 raise Exception("Singleton can't be created twice !")
119 mbse = MathBenchSearchEngine()
120 self.__search_methods = {"MathBench": mbse.search}
121 self.__desk_factory = None
122 self.__desk = None
123
124
125 - def show(self,txt):
126 """
127 Show the results in a frame.
128 """
129 if self.__desk==None:
130 self.__desk = self.__desk_factory()
131 dispatcher.connect(receiver=self._desk_closed,
132 signal='LibraryDeskClosed', sender=self.__desk)
133
134 self.__desk.showPage(txt)
135
137 """
138 When the desk is closed
139 """
140 self.__desk = None
141
143 """
144 Compile the search results in a unique html page.
145 """
146
147 search_res = ["""\
148 <html>
149 <title>Search results</title>
150
151 <body>
152 <H1> Search results for "%s" </H1>
153 <br>""" % search_query
154 ]
155 temp_search_res = []
156
157
158 for context in self.__search_methods.keys():
159 res_list = self.__search_methods[context](search_query)
160 if len(res_list)==0:
161 continue
162 else:
163
164 temp_search_res.append("""\
165 <br>
166 <H2>From %s</H2>
167 <br>
168 <ul>""" % DefangHTML(context))
169 for item in res_list:
170 temp_search_res.append("""\
171 <li><a href='%s'>%s</a></li>
172 <br>""" % item)
173
174 temp_search_res.append("""\
175 </ul>
176 <br>""")
177
178 if len(temp_search_res)==0:
179 search_res = ["""\
180 <html>
181 <title>Search results</title>
182
183 <body>
184 <H1> Sorry, no result for "%s" </H1>
185 <br>""" % search_query
186 ]
187 else:
188 search_res.extend(temp_search_res)
189
190
191 search_res.append("""\
192 </body>
193 </html>
194 """)
195 return os.linesep.join(search_res)
196
197
199 """
200 Display the welcome text in a widget
201 """
202 welcome_txt = """\
203 <html>
204
205 <title>Welcome</title>
206
207 <body>
208
209 <H1> Library Desk </H1>
210
211 <H2> About this desk</H2>
212
213 If you're looking for a precise answer, you may enter a search query
214 in the text area of the toolbar, press "Enter" (on your keyboard) and
215 the available answers will be shown to you.
216
217 <br>
218 <br>
219
220 Please also note that this viewer is buggy with external websites,
221 hence you should prefer going to online websites with your own
222 webbrowser.
223
224
225 <H2> About Python </H2>
226
227 <H3> References</H3>
228 <ul>
229 <li><a href="http://python.org">Python language</a>
230 <pre>http://python.org</pre></li>
231 <li><a href="http://docs.python.org/modindex.html">Modules index</a>
232 <pre>http://docs.python.org/modindex.html</pre></li>
233 <li><a href="http://starship.python.net/crew/theller/pyhelp.cgi">Online search</a>
234 <pre>http://starship.python.net/crew/theller/pyhelp.cgi</pre></li>
235 </ul>
236
237 <H3>Quick introductions</H3>
238 <ul>
239 <li><a href="http://docs.python.org/tut/tut.html">Python tutorial</a>
240 <pre>http://docs.python.org/tut/tut.html</pre></li>
241 <li><a href="http://wiki.python.org/moin/SimplePrograms">Simple code samples</a>
242 <pre>http://wiki.python.org/moin/SimplePrograms</pre></li>
243 </ul>
244
245 <H2> About Mathbench</H2>
246
247 <ul>
248 <li><a href="http://mathbench.sourceforge.net/">Mathbench Project</a>
249 <pre>http://mathbench.sourceforge.net</pre></li>
250 </ul>
251
252 </body>
253
254 </html>
255 """
256 self.show(welcome_txt)
257
259 """
260 Set the search method
261 """
262 self.__search_methods[context_name] = search_method
263
265 """
266 Record the previous search items
267 """
268 self.__desk.addToHistory(txt)
269
270
271
280 get = classmethod(get)
281
282 - def register(self,search_method,context_name):
283 """
284 Register a search method for a specific context (usually the
285 library imported by a precise plugin.)
286 """
287 librarian = self.get()
288 librarian.setSearchMethod(search_method,context_name)
289 logging.debug("Adding the search method from %s to the LibrarianSingleton" % context_name)
290 register = classmethod(register)
291
293 """
294 Set the factory that will be in charge of creating the desk
295 (ie the widget displaying the search results)
296 """
297 librarian = self.get()
298 librarian.__desk_factory = desk_factory
299 setDeskFactory = classmethod(setDeskFactory)
300
301
302 - def search(self,search_query):
312 search = classmethod(search)
313
320 welcome = classmethod(welcome)
321
322
333 popup = classmethod(popup)
334