Fixed export as HTML+ODT/PDF/RTF/TEX when text using substyles.

Sun, 03 Jan 2021 22:24:05 +0100

author
T.Rzepka <Tobias.Rzepka@gmail.com>
date
Sun, 03 Jan 2021 22:24:05 +0100
changeset 7949
17c0a4ec3cf0
parent 7948
6cbd0c086887
child 7950
cc96bf97e6c8

Fixed export as HTML+ODT/PDF/RTF/TEX when text using substyles.

eric6/QScintilla/Exporters/ExporterHTML.py file | annotate | diff | comparison | revisions
eric6/QScintilla/Exporters/ExporterPDF.py file | annotate | diff | comparison | revisions
eric6/QScintilla/Exporters/ExporterRTF.py file | annotate | diff | comparison | revisions
eric6/QScintilla/Exporters/ExporterTEX.py file | annotate | diff | comparison | revisions
eric6/QScintilla/QsciScintillaCompat.py file | annotate | diff | comparison | revisions
--- a/eric6/QScintilla/Exporters/ExporterHTML.py	Sun Jan 03 18:02:19 2021 +0100
+++ b/eric6/QScintilla/Exporters/ExporterHTML.py	Sun Jan 03 22:24:05 2021 +0100
@@ -165,6 +165,28 @@
                             html += '''    font-size: {0:d}pt;\n'''.format(
                                     QFontInfo(font).pointSize())
                         html += '''}\n'''
+                        
+                        # get substyles
+                        subs_start, subs_count = self.editor.getSubStyleRange(
+                            istyle)
+                        for subs_idx in range(subs_count):
+                            styleIsUsed[subs_idx - subs_start] = True
+                            font = lex.font(subs_start + subs_idx)
+                            colour = lex.color(subs_start + subs_idx)
+                            paper = lex.paper(subs_start + subs_idx)
+                            html += '.S{0:d} {{\n'.format(subs_idx - subs_start)
+                            if font.italic():
+                                html += '    font-style: italic;\n'
+                            if font.bold():
+                                html += '    font-weight: bold;\n'
+                            if wysiwyg:
+                                html += "    font-family: '{0}';\n".format(
+                                        font.family())
+                            html += '    color: {0};\n'.format(colour.name())
+                            if wysiwyg:
+                                html += '    font-size: {0:d}pt;\n'.format(
+                                        QFontInfo(font).pointSize())
+                            html += '}\n'
                     else:
                         styleIsUsed[istyle] = False
                 istyle += 1
--- a/eric6/QScintilla/Exporters/ExporterPDF.py	Sun Jan 03 18:02:19 2021 +0100
+++ b/eric6/QScintilla/Exporters/ExporterPDF.py	Sun Jan 03 22:24:05 2021 +0100
@@ -511,6 +511,22 @@
                         style.fore = self.__getPDFRGB(colour)
                         self.pr.style[istyle] = style
                     
+                        # get substyles
+                        subs_start, subs_count = self.editor.getSubStyleRange(
+                            istyle)
+                        for subs_idx in range(subs_count):
+                            style = PDFStyle()
+                            font = lex.font(subs_start + subs_idx)
+                            if font.italic():
+                                style.font |= 2
+                            if font.bold():
+                                style.font |= 1
+                            
+                            colour = lex.color(subs_start + subs_idx)
+                            style.fore = self.__getPDFRGB(colour)
+                            # styleAt returns negative numbers for substyles
+                            self.pr.style[subs_idx - subs_start] = style
+
                     # grab font size from default style
                     if istyle == QsciScintilla.STYLE_DEFAULT:
                         fontSize = QFontInfo(font).pointSize()
@@ -518,7 +534,7 @@
                             self.pr.fontSize += fontSize
                         else:
                             self.pr.fontSize = PDF_FONTSIZE_DEFAULT
-                
+                    
                 istyle += 1
         else:
             style = PDFStyle()
--- a/eric6/QScintilla/Exporters/ExporterRTF.py	Sun Jan 03 18:02:19 2021 +0100
+++ b/eric6/QScintilla/Exporters/ExporterRTF.py	Sun Jan 03 22:24:05 2021 +0100
@@ -119,170 +119,16 @@
             return
         
         self.editor.recolor(0, -1)
-        lex = self.editor.getLexer()
-        
+        tabs = Preferences.getEditorExporter("RTF/UseTabs")
         tabSize = self.editor.getEditorConfig("TabWidth")
         if tabSize == 0:
             tabSize = 4
-        wysiwyg = Preferences.getEditorExporter("RTF/WYSIWYG")
-        if wysiwyg:
-            if lex:
-                defaultFont = lex.font(QsciScintilla.STYLE_DEFAULT)
-            else:
-                defaultFont = Preferences.getEditorOtherFonts(
-                    "DefaultFont")
-        else:
-            defaultFont = Preferences.getEditorExporter("RTF/Font")
-        fontface = defaultFont.family()
-        fontsize = QFontInfo(defaultFont).pointSize() << 1
-        if fontsize == 0:
-            fontsize = 10 << 1
-        characterset = QsciScintilla.SC_CHARSET_DEFAULT
-        tabs = Preferences.getEditorExporter("RTF/UseTabs")
-        
-        if lex:
-            fgColour = lex.color(QsciScintilla.STYLE_DEFAULT)
-            bgColour = lex.paper(QsciScintilla.STYLE_DEFAULT)
-        else:
-            fgColour = self.editor.color()
-            bgColour = self.editor.paper()
         
         try:
             with E5OverrideCursor():
                 with open(filename, "w", encoding="utf-8") as f:
-                    
-                    styles = {}
-                    fonts = {}
-                    colors = {}
-                    lastStyle = ""
-                    
-                    f.write(self.RTF_HEADEROPEN + self.RTF_FONTDEFOPEN)
-                    fonts[0] = fontface
-                    fontCount = 1
-                    f.write(self.RTF_FONTDEF.format(0, characterset, fontface))
-                    colors[0] = fgColour
-                    colors[1] = bgColour
-                    colorCount = 2
+                    styles, fontsize = self.__prepareStyles(f)
                     
-                    if lex:
-                        istyle = 0
-                        while istyle <= QsciScintilla.STYLE_MAX:
-                            if (
-                                istyle < QsciScintilla.STYLE_DEFAULT or
-                                istyle > QsciScintilla.STYLE_LASTPREDEFINED
-                            ):
-                                if lex.description(istyle):
-                                    font = lex.font(istyle)
-                                    if wysiwyg:
-                                        fontKey = None
-                                        for key, value in list(fonts.items()):
-                                            if (
-                                                value.lower() ==
-                                                    font.family().lower()
-                                            ):
-                                                fontKey = key
-                                                break
-                                        if fontKey is None:
-                                            fonts[fontCount] = font.family()
-                                            f.write(self.RTF_FONTDEF.format(
-                                                fontCount, characterset,
-                                                font.family()))
-                                            fontKey = fontCount
-                                            fontCount += 1
-                                        lastStyle = (
-                                            self.RTF_SETFONTFACE +
-                                            "{0:d}".format(fontKey)
-                                        )
-                                    else:
-                                        lastStyle = self.RTF_SETFONTFACE + "0"
-                                    
-                                    if wysiwyg and QFontInfo(font).pointSize():
-                                        lastStyle += (
-                                            self.RTF_SETFONTSIZE +
-                                            "{0:d}".format(
-                                                QFontInfo(font).pointSize() <<
-                                                1)
-                                        )
-                                    else:
-                                        lastStyle += (
-                                            self.RTF_SETFONTSIZE +
-                                            "{0:d}".format(fontsize)
-                                        )
-                                    
-                                    sColour = lex.color(istyle)
-                                    sColourKey = None
-                                    for key, value in list(colors.items()):
-                                        if value == sColour:
-                                            sColourKey = key
-                                            break
-                                    if sColourKey is None:
-                                        colors[colorCount] = sColour
-                                        sColourKey = colorCount
-                                        colorCount += 1
-                                    lastStyle += (
-                                        self.RTF_SETCOLOR +
-                                        "{0:d}".format(sColourKey)
-                                    )
-                                    
-                                    sColour = lex.paper(istyle)
-                                    sColourKey = None
-                                    for key, value in list(colors.items()):
-                                        if value == sColour:
-                                            sColourKey = key
-                                            break
-                                    if sColourKey is None:
-                                        colors[colorCount] = sColour
-                                        sColourKey = colorCount
-                                        colorCount += 1
-                                    lastStyle += (
-                                        self.RTF_SETBACKGROUND +
-                                        "{0:d}".format(sColourKey)
-                                    )
-                                    
-                                    if font.bold():
-                                        lastStyle += self.RTF_BOLD_ON
-                                    else:
-                                        lastStyle += self.RTF_BOLD_OFF
-                                    if font.italic():
-                                        lastStyle += self.RTF_ITALIC_ON
-                                    else:
-                                        lastStyle += self.RTF_ITALIC_OFF
-                                    styles[istyle] = lastStyle
-                                else:
-                                    styles[istyle] = (
-                                        self.RTF_SETFONTFACE + "0" +
-                                        self.RTF_SETFONTSIZE +
-                                        "{0:d}".format(fontsize) +
-                                        self.RTF_SETCOLOR + "0" +
-                                        self.RTF_SETBACKGROUND + "1" +
-                                        self.RTF_BOLD_OFF +
-                                        self.RTF_ITALIC_OFF
-                                    )
-                            
-                            istyle += 1
-                    else:
-                        styles[0] = (
-                            self.RTF_SETFONTFACE + "0" +
-                            self.RTF_SETFONTSIZE +
-                            "{0:d}".format(fontsize) +
-                            self.RTF_SETCOLOR + "0" +
-                            self.RTF_SETBACKGROUND + "1" +
-                            self.RTF_BOLD_OFF +
-                            self.RTF_ITALIC_OFF
-                        )
-                    
-                    f.write(self.RTF_FONTDEFCLOSE + self.RTF_COLORDEFOPEN)
-                    for value in list(colors.values()):
-                        f.write(self.RTF_COLORDEF.format(
-                                value.red(), value.green(), value.blue()))
-                    f.write(self.RTF_COLORDEFCLOSE)
-                    f.write(self.RTF_INFOOPEN + self.RTF_COMMENT)
-                    f.write(time.strftime(self.RTF_CREATED))
-                    f.write(self.RTF_INFOCLOSE)
-                    f.write(self.RTF_HEADERCLOSE +
-                            self.RTF_BODYOPEN + self.RTF_SETFONTFACE + "0" +
-                            self.RTF_SETFONTSIZE + "{0:d}".format(fontsize) +
-                            self.RTF_SETCOLOR + "0 ")
                     lastStyle = (
                         self.RTF_SETFONTFACE + "0" +
                         self.RTF_SETFONTSIZE + "{0:d}".format(fontsize) +
@@ -373,3 +219,238 @@
                     """<p>The source could not be exported to"""
                     """ <b>{0}</b>.</p><p>Reason: {1}</p>""")
                 .format(filename, str(err)))
+    
+    def __prepareStyles(self, f):
+        """
+        Private method to generate and store the different styles.
+        
+        @param f filepointer to the open RTF
+        @type object
+        @return styles, fontsize
+        @rtype dict, int
+        """
+        styles = {}
+        fonts = {}
+        colors = {}
+        lastStyle = ""
+        
+        lex = self.editor.getLexer()
+        
+        wysiwyg = Preferences.getEditorExporter("RTF/WYSIWYG")
+        if wysiwyg:
+            if lex:
+                defaultFont = lex.font(QsciScintilla.STYLE_DEFAULT)
+            else:
+                defaultFont = Preferences.getEditorOtherFonts("DefaultFont")
+        else:
+            defaultFont = Preferences.getEditorExporter("RTF/Font")
+        fontface = defaultFont.family()
+        fontsize = QFontInfo(defaultFont).pointSize() << 1
+        if fontsize == 0:
+            fontsize = 10 << 1
+        characterset = QsciScintilla.SC_CHARSET_DEFAULT
+        
+        if lex:
+            fgColour = lex.color(QsciScintilla.STYLE_DEFAULT)
+            bgColour = lex.paper(QsciScintilla.STYLE_DEFAULT)
+        else:
+            fgColour = self.editor.color()
+            bgColour = self.editor.paper()
+        
+        f.write(self.RTF_HEADEROPEN + self.RTF_FONTDEFOPEN)
+        fonts[0] = fontface
+        fontCount = 1
+        f.write(self.RTF_FONTDEF.format(0, characterset, fontface))
+        colors[0] = fgColour
+        colors[1] = bgColour
+        colorCount = 2
+        
+        if lex:
+            istyle = 0
+            while istyle <= QsciScintilla.STYLE_MAX:
+                if (
+                    istyle < QsciScintilla.STYLE_DEFAULT or
+                    istyle > QsciScintilla.STYLE_LASTPREDEFINED
+                ):
+                    if lex.description(istyle):
+                        font = lex.font(istyle)
+                        lastStyle = self.RTF_SETFONTFACE
+                        if wysiwyg:
+                            fontKey = None
+                            for key, value in fonts.items():
+                                if value.lower() == font.family().lower():
+                                    fontKey = key
+                                    break
+                            else:
+                                fonts[fontCount] = font.family()
+                                f.write(self.RTF_FONTDEF.format(
+                                    fontCount, characterset,
+                                    font.family()))
+                                fontKey = fontCount
+                                fontCount += 1
+                            
+                            lastStyle += "{0:d}".format(fontKey)
+                        else:
+                            lastStyle += "0"
+                        
+                        lastStyle += self.RTF_SETFONTSIZE
+                        if wysiwyg and QFontInfo(font).pointSize():
+                            lastStyle += (
+                                "{0:d}".format(
+                                    QFontInfo(font).pointSize() << 1)
+                            )
+                        else:
+                            lastStyle += "{0:d}".format(fontsize)
+                        
+                        sColour = lex.color(istyle)
+                        sColourKey = None
+                        for key, value in colors.items():
+                            if value == sColour:
+                                sColourKey = key
+                                break
+                        else:
+                            colors[colorCount] = sColour
+                            sColourKey = colorCount
+                            colorCount += 1
+                        lastStyle += (
+                            self.RTF_SETCOLOR +
+                            "{0:d}".format(sColourKey)
+                        )
+                        
+                        sColour = lex.paper(istyle)
+                        sColourKey = None
+                        for key, value in colors.items():
+                            if value == sColour:
+                                sColourKey = key
+                                break
+                        else:
+                            colors[colorCount] = sColour
+                            sColourKey = colorCount
+                            colorCount += 1
+                        
+                        lastStyle += (
+                            self.RTF_SETBACKGROUND +
+                            "{0:d}".format(sColourKey)
+                        )
+                        
+                        if font.bold():
+                            lastStyle += self.RTF_BOLD_ON
+                        else:
+                            lastStyle += self.RTF_BOLD_OFF
+                        if font.italic():
+                            lastStyle += self.RTF_ITALIC_ON
+                        else:
+                            lastStyle += self.RTF_ITALIC_OFF
+                        styles[istyle] = lastStyle
+                        
+                        # get substyles
+                        subs_start, subs_count = self.editor.getSubStyleRange(
+                            istyle)
+                        for subs_idx in range(subs_count):
+                            font = lex.font(subs_start + subs_idx)
+                            lastStyle = self.RTF_SETFONTFACE
+                            if wysiwyg:
+                                fontKey = None
+                                for key, value in fonts.items():
+                                    if value.lower() == font.family().lower():
+                                        fontKey = key
+                                        break
+                                else:
+                                    fonts[fontCount] = font.family()
+                                    f.write(self.RTF_FONTDEF.format(
+                                        fontCount, characterset,
+                                        font.family()))
+                                    fontKey = fontCount
+                                    fontCount += 1
+                                
+                                lastStyle += "{0:d}".format(fontKey)
+                            else:
+                                lastStyle += "0"
+                            
+                            lastStyle += self.RTF_SETFONTSIZE
+                            if wysiwyg and QFontInfo(font).pointSize():
+                                lastStyle += (
+                                    "{0:d}".format(
+                                        QFontInfo(font).pointSize() << 1)
+                                )
+                            else:
+                                lastStyle += "{0:d}".format(fontsize)
+                            
+                            sColour = lex.color(subs_start + subs_idx)
+                            sColourKey = None
+                            for key, value in colors.items():
+                                if value == sColour:
+                                    sColourKey = key
+                                    break
+                            else:
+                                colors[colorCount] = sColour
+                                sColourKey = colorCount
+                                colorCount += 1
+                            lastStyle += (
+                                self.RTF_SETCOLOR +
+                                "{0:d}".format(sColourKey)
+                            )
+                            
+                            sColour = lex.paper(subs_start + subs_idx)
+                            sColourKey = None
+                            for key, value in colors.items():
+                                if value == sColour:
+                                    sColourKey = key
+                                    break
+                            else:
+                                colors[colorCount] = sColour
+                                sColourKey = colorCount
+                                colorCount += 1
+                            
+                            lastStyle += (
+                                self.RTF_SETBACKGROUND +
+                                "{0:d}".format(sColourKey)
+                            )
+                            
+                            if font.bold():
+                                lastStyle += self.RTF_BOLD_ON
+                            else:
+                                lastStyle += self.RTF_BOLD_OFF
+                            if font.italic():
+                                lastStyle += self.RTF_ITALIC_ON
+                            else:
+                                lastStyle += self.RTF_ITALIC_OFF
+                            styles[subs_idx - subs_start] = lastStyle
+                        
+                    else:
+                        styles[istyle] = (
+                            self.RTF_SETFONTFACE + "0" +
+                            self.RTF_SETFONTSIZE +
+                            "{0:d}".format(fontsize) +
+                            self.RTF_SETCOLOR + "0" +
+                            self.RTF_SETBACKGROUND + "1" +
+                            self.RTF_BOLD_OFF +
+                            self.RTF_ITALIC_OFF
+                        )
+                
+                istyle += 1
+        else:
+            styles[0] = (
+                self.RTF_SETFONTFACE + "0" +
+                self.RTF_SETFONTSIZE +
+                "{0:d}".format(fontsize) +
+                self.RTF_SETCOLOR + "0" +
+                self.RTF_SETBACKGROUND + "1" +
+                self.RTF_BOLD_OFF +
+                self.RTF_ITALIC_OFF
+            )
+        
+        f.write(self.RTF_FONTDEFCLOSE + self.RTF_COLORDEFOPEN)
+        for value in colors.values():
+            f.write(self.RTF_COLORDEF.format(
+                    value.red(), value.green(), value.blue()))
+        f.write(self.RTF_COLORDEFCLOSE)
+        f.write(self.RTF_INFOOPEN + self.RTF_COMMENT)
+        f.write(time.strftime(self.RTF_CREATED))
+        f.write(self.RTF_INFOCLOSE)
+        f.write(self.RTF_HEADERCLOSE +
+                self.RTF_BODYOPEN + self.RTF_SETFONTFACE + "0" +
+                self.RTF_SETFONTSIZE + "{0:d}".format(fontsize) +
+                self.RTF_SETCOLOR + "0 ")
+        
+        return styles, fontsize
--- a/eric6/QScintilla/Exporters/ExporterTEX.py	Sun Jan 03 18:02:19 2021 +0100
+++ b/eric6/QScintilla/Exporters/ExporterTEX.py	Sun Jan 03 22:24:05 2021 +0100
@@ -26,7 +26,7 @@
     """
     Class implementing an exporter for TeX.
     """
-    CHARZ = ord('z') - ord('a') + 1
+    CHARZ = 26
     
     def __init__(self, editor, parent=None):
         """
@@ -66,11 +66,17 @@
         @return style name string (string)
         """
         buf = ""
+        if style >= 0:
+            start = ord('a')
+        else:
+            start = ord('A')
+            style = abs(style)
+        
         if style == 0:
             buf = "a"
         else:
             while style > 0:
-                buf += chr(ord('a') + (style % self.CHARZ))
+                buf += chr(start + (style % self.CHARZ))
                 style //= self.CHARZ
         return buf
     
@@ -188,6 +194,21 @@
                                     
                                     self.__defineTexStyle(
                                         font, colour, paper, f, istyle)
+                                    # get substyles
+                                    subs_start, subs_count = (
+                                        self.editor.getSubStyleRange(istyle)
+                                    )
+                                    for subs_idx in range(subs_count):
+                                        font = lex.font(subs_start + subs_idx)
+                                        colour = lex.color(
+                                            subs_start + subs_idx)
+                                        paper = lex.paper(
+                                            subs_start + subs_idx)
+                                        
+                                        self.__defineTexStyle(
+                                            font, colour, paper, f,
+                                            subs_idx - subs_start)
+                                    
                             istyle += 1
                     else:
                         colour = self.editor.color()
--- a/eric6/QScintilla/QsciScintillaCompat.py	Sun Jan 03 18:02:19 2021 +0100
+++ b/eric6/QScintilla/QsciScintillaCompat.py	Sun Jan 03 22:24:05 2021 +0100
@@ -216,6 +216,21 @@
         """
         return self.styleAt(self.currentPosition())
     
+    def getSubStyleRange(self, styleNr):
+        """
+        Public method to get the sub style range for given style number.
+        
+        @param styleNr Number of the base style
+        @type int
+        @return start index of the sub style and their count
+        @rtype int, int
+        """
+        start = self.SendScintilla(QsciScintilla.SCI_GETSUBSTYLESSTART,
+            styleNr)
+        count = self.SendScintilla(QsciScintilla.SCI_GETSUBSTYLESLENGTH,
+            styleNr)
+        return start, count
+    
     def getEndStyled(self):
         """
         Public method to get the last styled position.

eric ide

mercurial