UI/Previewers/PreviewerHTML.py

changeset 5837
9ef6a28f1694
parent 5801
d3548bec88d1
child 5845
f3d2172d663e
equal deleted inserted replaced
5836:159e6057ad34 5837:9ef6a28f1694
8 """ 8 """
9 9
10 from __future__ import unicode_literals 10 from __future__ import unicode_literals
11 11
12 try: # Only for Py2 12 try: # Only for Py2
13 basestring
14 import StringIO as io # __IGNORE_EXCEPTION__ 13 import StringIO as io # __IGNORE_EXCEPTION__
15 except (ImportError, NameError): 14 except (ImportError, NameError):
16 import io # __IGNORE_WARNING__ 15 import io # __IGNORE_WARNING__
17 16
18 import os 17 import os
190 189
191 if bool(editor.text()): 190 if bool(editor.text()):
192 self.__processingThread.process( 191 self.__processingThread.process(
193 fn, language, editor.text(), 192 fn, language, editor.text(),
194 self.ssiCheckBox.isChecked(), rootPath, 193 self.ssiCheckBox.isChecked(), rootPath,
195 Preferences.getEditor("PreviewRestUseSphinx")) 194 Preferences.getEditor("PreviewRestUseSphinx"),
195 Preferences.getEditor("PreviewMarkdownNLtoBR"),
196 Preferences.getEditor("PreviewMarkdownHTMLFormat"),
197 Preferences.getEditor("PreviewRestDocutilsHTMLFormat"))
196 198
197 def __setHtml(self, filePath, html): 199 def __setHtml(self, filePath, html):
198 """ 200 """
199 Private method to set the HTML to the view and restore the scroll bars 201 Private method to set the HTML to the view and restore the scroll bars
200 positions. 202 positions.
355 super(PreviewProcessingThread, self).__init__() 357 super(PreviewProcessingThread, self).__init__()
356 358
357 self.__lock = threading.Lock() 359 self.__lock = threading.Lock()
358 360
359 def process(self, filePath, language, text, ssiEnabled, rootPath, 361 def process(self, filePath, language, text, ssiEnabled, rootPath,
360 useSphinx): 362 useSphinx, convertNewLineToBreak, markdownHtmlFormat,
363 restDocutilsHtmlFormat):
361 """ 364 """
362 Public method to convert the given text to HTML. 365 Public method to convert the given text to HTML.
363 366
364 @param filePath file path of the text (string) 367 @param filePath file path of the text (string)
365 @param language language of the text (string) 368 @param language language of the text (string)
367 @param ssiEnabled flag indicating to do some (limited) SSI processing 370 @param ssiEnabled flag indicating to do some (limited) SSI processing
368 (boolean) 371 (boolean)
369 @param rootPath root path to be used for SSI processing (str) 372 @param rootPath root path to be used for SSI processing (str)
370 @param useSphinx flag indicating to use Sphinx to generate the 373 @param useSphinx flag indicating to use Sphinx to generate the
371 ReST preview (boolean) 374 ReST preview (boolean)
375 @param convertNewLineToBreak flag indicating to convert new lines
376 to HTML break (Markdown only) (boolean)
377 @param markdownHtmlFormat HTML format to be generated by markdown
378 (string)
379 @param restDocutilsHtmlFormat HTML format to be generated by docutils
380 (string)
372 """ 381 """
373 with self.__lock: 382 with self.__lock:
374 self.__filePath = filePath 383 self.__filePath = filePath
375 self.__language = language 384 self.__language = language
376 self.__text = text 385 self.__text = text
377 self.__ssiEnabled = ssiEnabled 386 self.__ssiEnabled = ssiEnabled
378 self.__rootPath = rootPath 387 self.__rootPath = rootPath
379 self.__haveData = True 388 self.__haveData = True
380 self.__useSphinx = useSphinx 389 self.__useSphinx = useSphinx
390 self.__convertNewLineToBreak = convertNewLineToBreak
391 self.__markdownHtmlFormat = markdownHtmlFormat
392 self.__restDocutilsHtmlFormat = restDocutilsHtmlFormat
381 if not self.isRunning(): 393 if not self.isRunning():
382 self.start(QThread.LowPriority) 394 self.start(QThread.LowPriority)
383 395
384 def run(self): 396 def run(self):
385 """ 397 """
392 language = self.__language 404 language = self.__language
393 text = self.__text 405 text = self.__text
394 ssiEnabled = self.__ssiEnabled 406 ssiEnabled = self.__ssiEnabled
395 rootPath = self.__rootPath 407 rootPath = self.__rootPath
396 useSphinx = self.__useSphinx 408 useSphinx = self.__useSphinx
409 convertNewLineToBreak = self.__convertNewLineToBreak
410 markdownHtmlFormat = self.__markdownHtmlFormat
411 restDocutilsHtmlFormat = self.__restDocutilsHtmlFormat
412
397 self.__haveData = False 413 self.__haveData = False
398 414
399 html = self.__getHtml(language, text, ssiEnabled, filePath, 415 html = self.__getHtml(language, text, ssiEnabled, filePath,
400 rootPath, useSphinx) 416 rootPath, useSphinx, convertNewLineToBreak,
417 markdownHtmlFormat, restDocutilsHtmlFormat)
401 418
402 with self.__lock: 419 with self.__lock:
403 if not self.__haveData: 420 if not self.__haveData:
404 self.htmlReady.emit(filePath, html) 421 self.htmlReady.emit(filePath, html)
405 break 422 break
406 # else - next iteration 423 # else - next iteration
407 424
408 def __getHtml(self, language, text, ssiEnabled, filePath, rootPath, 425 def __getHtml(self, language, text, ssiEnabled, filePath, rootPath,
409 useSphinx): 426 useSphinx, convertNewLineToBreak, markdownHtmlFormat,
427 restDocutilsHtmlFormat):
410 """ 428 """
411 Private method to process the given text depending upon the given 429 Private method to process the given text depending upon the given
412 language. 430 language.
413 431
414 @param language language of the text (string) 432 @param language language of the text (string)
417 (boolean) 435 (boolean)
418 @param filePath file path of the text (string) 436 @param filePath file path of the text (string)
419 @param rootPath root path to be used for SSI processing (str) 437 @param rootPath root path to be used for SSI processing (str)
420 @param useSphinx flag indicating to use Sphinx to generate the 438 @param useSphinx flag indicating to use Sphinx to generate the
421 ReST preview (boolean) 439 ReST preview (boolean)
440 @param convertNewLineToBreak flag indicating to convert new lines
441 to HTML break (Markdown only) (boolean)
442 @param markdownHtmlFormat HTML format to be generated by markdown
443 (string)
444 @param restDocutilsHtmlFormat HTML format to be generated by docutils
445 (string)
422 @return processed HTML text (string) 446 @return processed HTML text (string)
423 """ 447 """
424 if language == "HTML": 448 if language == "HTML":
425 if ssiEnabled: 449 if ssiEnabled:
426 return self.__processSSI(text, filePath, rootPath) 450 return self.__processSSI(text, filePath, rootPath)
427 else: 451 else:
428 return text 452 return text
429 elif language == "Markdown": 453 elif language == "Markdown":
430 return self.__convertMarkdown(text) 454 return self.__convertMarkdown(text, convertNewLineToBreak,
455 markdownHtmlFormat)
431 elif language == "ReST": 456 elif language == "ReST":
432 return self.__convertReST(text, useSphinx) 457 return self.__convertReST(text, useSphinx, restDocutilsHtmlFormat)
433 else: 458 else:
434 return self.tr( 459 return self.tr(
435 "<p>No preview available for this type of file.</p>") 460 "<p>No preview available for this type of file.</p>")
436 461
437 def __processSSI(self, txt, filename, root): 462 def __processSSI(self, txt, filename, root):
479 incTxt = "" 504 incTxt = ""
480 txt = txt[:incMatch.start(0)] + incTxt + txt[incMatch.end(0):] 505 txt = txt[:incMatch.start(0)] + incTxt + txt[incMatch.end(0):]
481 506
482 return txt 507 return txt
483 508
484 def __convertReST(self, text, useSphinx): 509 def __convertReST(self, text, useSphinx, restDocutilsHtmlFormat):
485 """ 510 """
486 Private method to convert ReST text into HTML. 511 Private method to convert ReST text into HTML.
487 512
488 @param text text to be processed (string) 513 @param text text to be processed (string)
489 @param useSphinx flag indicating to use Sphinx to generate the 514 @param useSphinx flag indicating to use Sphinx to generate the
490 ReST preview (boolean) 515 ReST preview (boolean)
516 @param restDocutilsHtmlFormat HTML format to be generated by docutils
517 (string)
491 @return processed HTML (string) 518 @return processed HTML (string)
492 """ 519 """
493 if useSphinx: 520 if useSphinx:
494 return self.__convertReSTSphinx(text) 521 return self.__convertReSTSphinx(text)
495 else: 522 else:
496 return self.__convertReSTDocutils(text) 523 return self.__convertReSTDocutils(text, restDocutilsHtmlFormat)
497 524
498 def __convertReSTSphinx(self, text): 525 def __convertReSTSphinx(self, text):
499 """ 526 """
500 Private method to convert ReST text into HTML using 'sphinx'. 527 Private method to convert ReST text into HTML using 'sphinx'.
501 528
541 finally: 568 finally:
542 shutil.rmtree(tempDir) 569 shutil.rmtree(tempDir)
543 570
544 return html 571 return html
545 572
546 def __convertReSTDocutils(self, text): 573 def __convertReSTDocutils(self, text, htmlFormat):
547 """ 574 """
548 Private method to convert ReST text into HTML using 'docutils'. 575 Private method to convert ReST text into HTML using 'docutils'.
549 576
550 @param text text to be processed (string) 577 @param text text to be processed (string)
578 @param htmlFormat HTML format to be generated (string)
551 @return processed HTML (string) 579 @return processed HTML (string)
552 """ 580 """
553 if 'sphinx' in sys.modules: 581 if 'sphinx' in sys.modules:
554 # Make sure any Sphinx polution of docutils has been removed. 582 # Make sure any Sphinx polution of docutils has been removed.
555 unloadKeys = [k for k in sys.modules.keys() 583 unloadKeys = [k for k in sys.modules.keys()
568 """this page.</a></p>""") 596 """this page.</a></p>""")
569 597
570 # redirect sys.stderr because we are not interested in it here 598 # redirect sys.stderr because we are not interested in it here
571 origStderr = sys.stderr 599 origStderr = sys.stderr
572 sys.stderr = io.StringIO() 600 sys.stderr = io.StringIO()
573 html = docutils.core.publish_string(text, writer_name='html')\ 601 html = docutils.core.publish_string(
574 .decode("utf-8") 602 text, writer_name=htmlFormat.lower()).decode("utf-8")
575 sys.stderr = origStderr 603 sys.stderr = origStderr
576 return html 604 return html
577 605
578 def __convertMarkdown(self, text): 606 def __convertMarkdown(self, text, convertNewLineToBreak, htmlFormat):
579 """ 607 """
580 Private method to convert Markdown text into HTML. 608 Private method to convert Markdown text into HTML.
581 609
582 @param text text to be processed (string) 610 @param text text to be processed (string)
611 @param convertNewLineToBreak flag indicating to convert new lines
612 to HTML break (Markdown only) (boolean)
613 @param htmlFormat HTML format to be generated by markdown (string)
583 @return processed HTML (string) 614 @return processed HTML (string)
584 """ 615 """
585 try: 616 try:
586 import markdown # __IGNORE_EXCEPTION__ 617 import markdown # __IGNORE_EXCEPTION__
587 except ImportError: 618 except ImportError:
595 try: 626 try:
596 import mdx_mathjax # __IGNORE_EXCEPTION__ __IGNORE_WARNING__ 627 import mdx_mathjax # __IGNORE_EXCEPTION__ __IGNORE_WARNING__
597 except ImportError: 628 except ImportError:
598 #mathjax doesn't require import statement if installed as extension 629 #mathjax doesn't require import statement if installed as extension
599 pass 630 pass
600 631
601 extensions = ['fenced_code', 'nl2br', 'extra'] 632 if convertNewLineToBreak:
633 extensions = ['fenced_code', 'nl2br', 'extra']
634 else:
635 extensions = ['fenced_code', 'extra']
602 636
603 # version 2.0 supports only extension names, not instances 637 # version 2.0 supports only extension names, not instances
604 if markdown.version_info[0] > 2 or \ 638 if markdown.version_info[0] > 2 or \
605 (markdown.version_info[0] == 2 and 639 (markdown.version_info[0] == 2 and
606 markdown.version_info[1] > 0): 640 markdown.version_info[1] > 0):
623 md.inlinePatterns.add('del', del_tag, '>not_strong') 657 md.inlinePatterns.add('del', del_tag, '>not_strong')
624 658
625 extensions.append(_StrikeThroughExtension()) 659 extensions.append(_StrikeThroughExtension())
626 660
627 try: 661 try:
628 return markdown.markdown(text, extensions + ['mathjax']) 662 return markdown.markdown(text, extensions=extensions + ['mathjax'],
663 output_format=htmlFormat.lower())
629 except (ImportError, ValueError): 664 except (ImportError, ValueError):
630 # markdown raises ValueError or ImportError, depends on version 665 # markdown raises ValueError or ImportError, depends on version
631 # It is not clear, how to distinguish missing mathjax from other 666 # It is not clear, how to distinguish missing mathjax from other
632 # errors. So keep going without mathjax. 667 # errors. So keep going without mathjax.
633 return markdown.markdown(text, extensions) 668 return markdown.markdown(text, extensions=extensions,
669 output_format=htmlFormat.lower())

eric ide

mercurial