33 |
34 |
34 @param editor reference to the editor object (QScintilla.Editor.Editor) |
35 @param editor reference to the editor object (QScintilla.Editor.Editor) |
35 """ |
36 """ |
36 self.editor = editor |
37 self.editor = editor |
37 |
38 |
38 def generate(self, tabSize = 4, useTabs = False, wysiwyg = True, folding = False, |
39 def generate(self, tabSize=4, useTabs=False, wysiwyg=True, folding=False, |
39 onlyStylesUsed = False, titleFullPath = False): |
40 onlyStylesUsed=False, titleFullPath=False): |
40 """ |
41 """ |
41 Public method to generate HTML for the source editor. |
42 Public method to generate HTML for the source editor. |
42 |
43 |
43 @keyparam tabSize size of tabs (integer) |
44 @keyparam tabSize size of tabs (integer) |
44 @keyparam useTabs flag indicating the use of tab characters (boolean) |
45 @keyparam useTabs flag indicating the use of tab characters (boolean) |
210 style = self.editor.styleAt(pos) |
211 style = self.editor.styleAt(pos) |
211 if style != styleCurrent: |
212 if style != styleCurrent: |
212 if inStyleSpan: |
213 if inStyleSpan: |
213 html += '''</span>''' |
214 html += '''</span>''' |
214 inStyleSpan = False |
215 inStyleSpan = False |
215 if ch not in [b'\r', b'\n']: # no need of a span for the EOL |
216 if ch not in [b'\r', b'\n']: # no need of a span for the EOL |
216 if styleIsUsed[style]: |
217 if styleIsUsed[style]: |
217 html += '''<span class="S{0:d}">'''.format(style) |
218 html += '''<span class="S{0:d}">'''.format(style) |
218 inStyleSpan = True |
219 inStyleSpan = True |
219 styleCurrent = style |
220 styleCurrent = style |
220 |
221 |
221 if ch == b' ': |
222 if ch == b' ': |
222 if wysiwyg: |
223 if wysiwyg: |
223 prevCh = b'' |
224 prevCh = b'' |
224 if column == 0: |
225 if column == 0: |
225 # at start of line, must put a |
226 # at start of line, must put a |
226 # because regular space will be collapsed |
227 # because regular space will be collapsed |
227 prevCh = b' ' |
228 prevCh = b' ' |
228 while pos < lengthDoc and self.editor.byteAt(pos) == b' ': |
229 while pos < lengthDoc and self.editor.byteAt(pos) == b' ': |
229 if prevCh != b' ': |
230 if prevCh != b' ': |
230 html += ' ' |
231 html += ' ' |
231 else: |
232 else: |
232 html += ''' ''' |
233 html += ''' ''' |
233 prevCh = self.editor.byteAt(pos) |
234 prevCh = self.editor.byteAt(pos) |
234 pos += 1 |
235 pos += 1 |
235 column += 1 |
236 column += 1 |
236 pos -= 1 |
237 pos -= 1 |
237 # the last incrementation will be done by the outer loop |
238 # the last incrementation will be done by the outer loop |
238 else: |
239 else: |
239 html += ' ' |
240 html += ' ' |
240 column += 1 |
241 column += 1 |
241 elif ch == b'\t': |
242 elif ch == b'\t': |
270 |
271 |
271 if newLevel < level: |
272 if newLevel < level: |
272 while levelStack[-1] > newLevel: |
273 while levelStack[-1] > newLevel: |
273 html += '''</span>''' |
274 html += '''</span>''' |
274 levelStack.pop() |
275 levelStack.pop() |
275 html += '\n' # here to get clean code |
276 html += '\n' # here to get clean code |
276 if newLevel > level: |
277 if newLevel > level: |
277 html += '''<span id="ln{0:d}">'''.format(line) |
278 html += '''<span id="ln{0:d}">'''.format(line) |
278 levelStack.append(newLevel) |
279 levelStack.append(newLevel) |
279 if self.editor.foldFlagsAt(line) & \ |
280 if self.editor.foldFlagsAt(line) & \ |
280 QsciScintilla.SC_FOLDLEVELHEADERFLAG: |
281 QsciScintilla.SC_FOLDLEVELHEADERFLAG: |
310 utf8Len = 4 |
311 utf8Len = 4 |
311 elif (utf8Ch[0] & 0xE0) == 0xE0: |
312 elif (utf8Ch[0] & 0xE0) == 0xE0: |
312 utf8Len = 3 |
313 utf8Len = 3 |
313 elif (utf8Ch[0] & 0xC0) == 0xC0: |
314 elif (utf8Ch[0] & 0xC0) == 0xC0: |
314 utf8Len = 2 |
315 utf8Len = 2 |
315 column -= 1 # will be incremented again later |
316 column -= 1 # will be incremented again later |
316 elif len(utf8Ch) == utf8Len: |
317 elif len(utf8Ch) == utf8Len: |
317 ch = utf8Ch.decode('utf8') |
318 ch = utf8Ch.decode('utf8') |
318 html += Utilities.html_encode(ch) |
319 html += Utilities.html_encode(ch) |
319 utf8Ch = b"" |
320 utf8Ch = b"" |
320 utf8Len = 0 |
321 utf8Len = 0 |
321 else: |
322 else: |
322 column -= 1 # will be incremented again later |
323 column -= 1 # will be incremented again later |
323 else: |
324 else: |
324 html += ch.decode() |
325 html += ch.decode() |
325 column += 1 |
326 column += 1 |
326 |
327 |
327 pos += 1 |
328 pos += 1 |
341 |
342 |
342 html += '''</body>\n</html>\n''' |
343 html += '''</body>\n</html>\n''' |
343 |
344 |
344 return html |
345 return html |
345 |
346 |
|
347 |
346 class ExporterHTML(ExporterBase): |
348 class ExporterHTML(ExporterBase): |
347 """ |
349 """ |
348 Class implementing an exporter for HTML. |
350 Class implementing an exporter for HTML. |
349 """ |
351 """ |
350 def __init__(self, editor, parent = None): |
352 def __init__(self, editor, parent=None): |
351 """ |
353 """ |
352 Constructor |
354 Constructor |
353 |
355 |
354 @param editor reference to the editor object (QScintilla.Editor.Editor) |
356 @param editor reference to the editor object (QScintilla.Editor.Editor) |
355 @param parent parent object of the exporter (QObject) |
357 @param parent parent object of the exporter (QObject) |
377 titleFullPath = Preferences.getEditorExporter("HTML/FullPathAsTitle") |
379 titleFullPath = Preferences.getEditorExporter("HTML/FullPathAsTitle") |
378 tabs = Preferences.getEditorExporter("HTML/UseTabs") |
380 tabs = Preferences.getEditorExporter("HTML/UseTabs") |
379 |
381 |
380 generator = HTMLGenerator(self.editor) |
382 generator = HTMLGenerator(self.editor) |
381 html = generator.generate( |
383 html = generator.generate( |
382 tabSize = tabSize, |
384 tabSize=tabSize, |
383 useTabs = tabs, |
385 useTabs=tabs, |
384 wysiwyg = wysiwyg, |
386 wysiwyg=wysiwyg, |
385 folding = folding, |
387 folding=folding, |
386 onlyStylesUsed = onlyStylesUsed, |
388 onlyStylesUsed=onlyStylesUsed, |
387 titleFullPath = titleFullPath |
389 titleFullPath=titleFullPath |
388 ) |
390 ) |
389 |
391 |
390 try: |
392 try: |
391 f = open(filename, "w", encoding = "utf-8") |
393 f = open(filename, "w", encoding="utf-8") |
392 f.write(html) |
394 f.write(html) |
393 f.close() |
395 f.close() |
394 except IOError as err: |
396 except IOError as err: |
395 QApplication.restoreOverrideCursor() |
397 QApplication.restoreOverrideCursor() |
396 E5MessageBox.critical(self.editor, |
398 E5MessageBox.critical(self.editor, |