I have had a program in PyQt5. The program have had a QTextEdit field for printing clear HTML using Python’s method html.escape(). Every string have added in the field using .append(). Some tags in some strings needed to be highlighted. And I have used next code:
self.textEdit.append('{0}{color}{1}{endcolor}{2}'.format(begin,
color_text, end, color='<font color="red">', endcolor='</font>')
Lately I found a module in Internet that can print strings number. This module use QPlainTextEdit. Also I found a module for syntax highlight, that was arranged by QSyntaxHighlighter and it’s for QPlainTextEdit too. It all works good, but now I can‘t highlight additional tags using code above. I have to highlight not only html syntax, but also additional some tags by other color. I tried to create another QSyntaxHighlighter that would highlight a whole text it get.
def format(color, style=''):
_color = QColor()
_color.setNamedColor(color)
_format = QTextCharFormat()
_format.setForeground(_color)
return _format
class PythonHighlighter (QSyntaxHighlighter):
def __init__(self, document):
QSyntaxHighlighter.__init__(self, document)
def highlightBlock(self, text):
self.setFormat(0, len(text), format('red'))
self.setCurrentBlockState(0)
Then in necessary place I write:
highlight = syntax.PythonHighlighter(self.textEdit.document())
self.textEdit.show()
self.textEdit.appendPlainText(...)
I thought to apply this highlighter to places of html that between{color} and {endcolor} above in code. Can I apply highlighter only to part of field? How? And if I can't, which are there methods to solve my problem?
P.S. Sorry for mistakes in my English. You can tell me about them.
Related
So, the the tkinter text editor!
The editor obviously needs to have text styles, which need to change typed text to whatever formatting is currently selected, using tags. But the problem is that the tag name needs to change when the formatting changes, otherwise the tag would be applied to the whole text.
(This was a problem that I was struggling to identify for quite some time)
To avoid this, you would need a LOT of tags (like bold, both, calibri etc), so the code would look like this
if style == 'bold':
tag_add('bold', 'insert -1c', 'insert')
tag_configure('bold', font=('Calibri', 12, 'bold'))
if stlye == 'italic':
etc etc
This is awful code, and makes different fonts/sizes impossible.
Is there a correct way of organising multiple tags like this, something like
tag.add(currentstyle, 'insert -1c', 'insert')
tag.config(currentstyle, font=(currentfont, currentsize, currentweight, currentslant))
Thanks for your help
UPDATE
solved with no small amount of help from Bryan
tagname = '{}-{}-{}-{}'.format(font, fontsize, weight, slant)
textbox.tag_add(tagname, 'insert -1c', 'insert')
textbox.tag_configure(tagname, font=(font, fontsize, weight, slant))
now every tag has a unique name
Yes, you will need to create a unique tag for every different font you use. In practice this isn't so bad, because most documents only use 3-4 variations, or perhaps a worst case of maybe a dozen. The only real difficulty is that if you want both bold and italics you have to create a bold tag, an italics tag, and a bold-italics tag.
This is awful code, and makes different fonts/sizes impossible.
It doesn't make it impossible, just slightly difficult. Your code is actually pretty close to how you would do it.
When a user changes the style of a character, you need to create a canonical form for the style name by combining the current style and any new attributes. For example, if the character is currently bold 12 point and they change it to italic 14 point, the new tag might be "italic-12". If they want to keep the bold it might be "bold-italic-12". You then need to check for whether you have a tag by that name, and create it if you don't, then remove any previous font tag and add the new font tag.
This is really only a problem with fonts. For other attributes such as colors and borders you can simply use all the different tags separately (ie: if you create a tag for "background-blue" and "foreground-red", you can apply both of those tags separately to the text.
I provide an example that does something similar to this here: https://stackoverflow.com/a/3736494/7432
I'm trying to create a .docx document via python, but both methods I've found lacks one of my needed features:
Set background color of specific cells in a table (to green).
Add page-breaks.
I have tried with:
python-docx: As far as I can tell, I can't set the background color of specific cells in a table. I can however add page-breaks.
py2docx: Support for coloring of cells, but I haven't found a method to add a page-break.
Is there a way to do both features in any of these modules? If not, is there another one?
Thanks.
Word documents are actually compressed rar files. I saved a .docx with a single page break in it, and then un-rar'd the .docx file. There are a lot of xml files in there, but I found the one containing the page break. In xml, it looks like:
<w:r>
<w:br w:type="page"/>
</w:r>
So then I looked up py2docx's source code, and found that the classes it uses (Text, InlineText, Block, Table, etc) have an xml attribute and a _get_xml function.
py2docx's Break class looks like this:
class Break(Text):
def __init__(self):
self.xml = """<w:br/>"""
def _get_xml(self):
return self.xml
This is for regular newlines I believe. But what we need is a page break. So I made a similar class, like this:
from py2docx.elements.text import Text
class PageBreak(Text):
def __init__(self):
self.xml = """<w:r><w:br w:type="page"/></w:r>"""
def _get_xml(self):
return self.xml
With that declared, I can use it like any other py2docx class:
doc.append(Block(PageBreak()))
I used the PageBreak in a new .docx and exported it, and it worked as expected. I honestly haven't tried sticking it in every possible place that the py2docx library allows, but I'm confident it should work.
I wanna add a link in a text but a found a solution, but it's don't work as well...
Then my code look like :
self.AddText('Some text here...'.decode('utf-8'))
self.AddText('Some text here too...'.decode('utf-8'))
self.linkweb = hl.HyperLinkCtrl(self, wx.ID_ANY, 'my_adress#box.net'.decode('utf-8'), URL="http://www.my_website.com/", pos=(545,88))
Then have you some ideas too make that more simple, cause here, i have to put my linkweb with the position in my frame... It's not really easy, and don't have the same positions, on all PC...
Thanks you all ;)
The wx.richtext.RichTextCtrl supports inserting hyperlinks in its text. You might be able to use the wx.TE_RICH style flag with a regular wx.TextCtrl to get the same capabilities, but I'm not sure if that will work. See the wxPython demo for a good example.
ok so I'm writing a function in python which takes a text document which is tagged with tags like ===, ==, ---, #text# etc. etc. (alot like wikipedia). Now my program basically has to replace those with HTML tags such as &ndash, &mdash, <>text etc. so that they can be displayed properly in a browser. This is what i've got so far:
def tag_change ():
for () in range ()
sub('--', '–')
sub('---', '—')
sub('''*''', '<i>*</i>')
sub("'''*'''", '<b>*</b>')
sub("==*==", "<h1>*</h1>")
sub("#*#", "<li>*</li>")
Am I on the right track? Or is there something else I need to include? I'm fairly new to this
Your best bet (if you want to write your own function and avoid using an existing tool) is to use regex, which is simple enough
import re
def subst(text):
str = '#text#'
capture = re.search('#(.+)#', str)
return '<li>'+ capture.group(1)+ '</li>'
I hope you get the idea
you could also use patterns like '==(.+)==' and so forth to capture what you want.
You can view this post to learn more about using re.search and re.match
https://stackoverflow.com/a/180993/2152321
You can also learn more about regex pattern construction here
http://www.tutorialspoint.com/python/python_reg_expressions.htm
I'm trying to create a custom syntax for my users to format some html
so a user can enter something like:
**some text here**
the some more text down here
**Another bunch of stuff**
then some other junk
and I get:
<h1>some text here</h2>
<p>the some more text down here</p>
<h1>Another bunch of stuff</h1>
<p>then some other junk</p>
and hopefully leave some room to make up other tags as I need them
edit:
So my question is how would I write the regex function to convert some given text and have it find every instance of an opening and closing ** and replace them with the appropriate or tags.
i have:
import re
header_pattern = re.compile(r'(?P**)(?P.*)(?P**)', re.MULTILINE)
def format_headers(text):
def process_match(m):
return "<h2>%s</h2>" % m.group('header')
new_text = header_pattern.sub(process_match, text)
print new_text
but this only grabs the first ** and last ** and ignores ones in the middle.
Use some standard solution. Like Markdown. Its is most preferable.
To match your header strings use r'\*\*(.*?)\*\*'. See example
>>> re.sub(r'\*\*(.*?)\*\*','<h1>\\1</h1>', '**some text here** and **another**')
'<h1>some text here</h1> and <h1>another</h1>'
Is there any reason you couldn't use a simple template language like Cheetah and build the logic into even handlers? Cheetah would allow you to create a template objects that contain a set of methods useful for manipulating HTML.
I had a similar issue a few weeks back when I was trying to use CherryPy to create a webpage, in the tutorials I found Cheetah templates and it made writing the forms so much easier!