I'm trying to make a SVG file connected to a web scraper.
How do I change font and text size with svgwrite? I understand that I have to define a CSS style and somehow connect that to the text object. But how is this made?
Here's the code I have so far
import svgwrite
svg_document = svgwrite.Drawing(filename = "test-svgwrite3.svg",
size = ("1200px", "800px"))
#This is the line I'm stuck at
#svg_document.add(svg_document.style('style="font-family: Arial; font-size : 34;'))
svg_document.add(svg_document.rect(insert = (900, 800),
size = ("200px", "100px"),
stroke_width = "1",
stroke = "black",
fill = "rgb(255,255,0)"))
svg_document.add(svg_document.text("Reported Crimes in Sweden",
insert = (410, 50),
fill = "rgb(255,255,0)",
#This is the connection to the first line that I'm stuck at
#style = 'style="font-family: Arial; font-size : 104;'))
print(svg_document.tostring())
svg_document.save()
Manfred Moitzi the maker of SvgWrite mailed me an more eleborated answer;
This has to be done by CSS, use the 'class_' or 'style' keyword args to set text properties:
dwg = svgwrite.Drawing()
with 'style' keyword arg:
g = dwg.g(style="font-size:30;font-family:Comic Sans MS, Arial;font-weight:bold;font-
style:oblique;stroke:black;stroke-width:1;fill:none")
g.add(dwg.text("your text", insert=(10,30))) # settings are valid for all text added to 'g'
dwg.add(g)
with 'class_' keyword arg:
Create a CSS file with content:
.myclass {
font-size:30;
font-family:Comic Sans MS, Arial;
font-weight:bold;
font-style:oblique;
stroke:black;
stroke-width:1;
fill:none;
}
see CSS reference: http://www.w3schools.com/cssref/default.asp
dwg.add_stylesheet(filename, title="sometext") # same rules as for html files
g = dwg.g(class_="myclass")
g.add(dwg.text("your text", insert=(10,30))) # settings are valid for all text added to 'g'
dwg.add(g)
With 'class_' and 'style' keyword args you can style every graphic object and they can be used at container objects.
The answer was quite simple;
svg_document.add(svg_document.text("Reported Crimes in Sweden",
insert = (410, 50),
fill = "rgb(255,255,0)",
style = "font-size:10px; font-family:Arial"))
Set font-size like this:
dwg = svgwrite.Drawing('test.svg', profile='tiny')
dwg.add(dwg.text('Test',insert = (30, 55),font_size="10px",fill='black'))
Related
I have the following bits of code that creates a toplevel window and parses a dictionary into a Text widget:
def escrito(**kwargs):
write_window = Toplevel(root)
#write_window.title(kwargs) (problematic code)
writing_box = tk.Text(write_window, font = ("calibri", 20), width = 60, height = 15, wrap=WORD)
writing_box.pack(expand = tk.YES, fill = tk.X)
writing_box.grid(row = 0, column = 0, sticky = 'nswe')
texto = '\n'.join(key + ":\n" + value for key, value in kwargs.items())
writing_box.insert("1.0", texto)
def septic_osteo():
escrito(**infections.Septic_arthritis)
Septic_arthritis = {
'Empirical Treatment':
'Flucloxacillin 2g IV 6-hourly',
'If non-severe penicillin allergy':
'Ceftriaxone IV 2g ONCE daily',
'If severe penicillin allergy OR if known to be colonised with
MRSA':
'Vancomycin infusion IV, Refer to Vancomycin Prescribing
Policy',
'If systemic signs of sepsis': 'Discuss with Consultant
Microbiologist'
}
So when I run the code, the escrito functions parses the dictionary and writes its content onto a text widget contained on a Toplevel window. What I would like to know is how to dynamically rename the Toplevel window with the dicitonary's name. I do know that I can do this:
def septic_osteo():
escrito(**infections.Septic_arthritis)
write_window.title('Septic_arthritis)
but I do have like 100 functions like the one above, so, aside from labour intensive, I am not sure is the more pythonic way, so, is there a way that the window can be renamed with the dictionary name? (i.e. 'Septic_arthritis)
Thanks
If your data is in an object named infections, with attributes such as Septic_arthritis, the most straight-forward solution is to pass the data and the attribute as separate arguments, and then use getattr to get the data for the particular infection.
It would look something like this:
def escrito(data, infection):
write_window = Toplevel(root)
write_window.title(infection)
writing_box = tk.Text(write_window, font = ("calibri", 20), width = 60, height = 15, wrap="word")
writing_box.pack(expand = tk.YES, fill = tk.X)
writing_box.grid(row = 0, column = 0, sticky = 'nswe')
texto = '\n'.join(key + ":\n" + value for key, value in getattr(data, infection).items())
writing_box.insert("1.0", texto)
The important bit about the above code is that it uses getattr(data, infection) to get the data for the given infection.
If you want to create a button to call this function, it might look something like this:
button = tk.Button(..., command=lambda: escrito(infections, "Septic_arthritis"))
This will call the command escrito with two arguments: the object that contains all of the infections, and the key to the specific piece of information you want to display.
customerqtyUI = Label(homeUI, text = (str('number of customer:'), customer) , font = ('calibri', 20), background="floral white", foreground = 'black')
this is my code👆.
May i know why i cannot combine the string and my variable 'customer' together?
My output👆 will have a {} and i cannot remove it
I'm not sure how tkinter works, but in this case, you've passed a tuple consisting of str('number of customer:') and customer to the text keyword argument. What you really want to do is combine 'number of customers:' with the customer variable. Try this:
customerqtyUI = Label(homeUI, text = f'number of customer: {customer}', font = ('calibri', 20), background="floral white", foreground = 'black')
text field accepts a string. Passing a tuple (or any other type) will be counted as undefined behaviour. So the solution becomes
Label(..., text = 'number of customer: ' + str(customer), ...)```
I'm using python-docx to put a text into MS Word. I can make it bold or center,but how to do both.
Here's the bold:
p=document.add_paragraph().add_run('test word')
p.font.size = Pt(16)
p.bold = True
Here's the center:
p=document.add_paragraph('test word')
p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
how to do both bold and center?
Separate between paragraph and run and define each:
p=document.add_paragraph()
p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
r=p.add_run('test word')
r.font.size = Pt(16)
r.bold = True
You can set p as the reference of this paragraph, and then use add_run() to add your text. Just like this:
p = document.add_paragraph()
p.add_run('test word').bold = True
p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
Sorry, I can't upload my picture, but I have tried it.
I have in a project created a helper-class that I call Text. We also add a function that adds the text to the document.
Now we can do this:
add_Text([Text("NORMAL TEXT "),Text("BOLD TEXT",bold=True)]
The function will make sure the runs are in the same paragraph. As the center paragraph is a property of the paragraph I added it outside:
add_Text([Text("NORMAL TEXT "),Text("BOLD TEXT",bold=True), align='center']
Here is a full example of what I mean:
from docx import Document
from docx.shared import Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
class Text:
def __init__(self, text, bold=False, italic=False):
self.text = text
self.bold = bold
self.italic = italic
def add_text(textitems, align=False):
p = document.add_paragraph('')
if align == 'center':
p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
for t in textitems:
r = p.add_run(t.text)
if t.bold:
r.bold = True
if t.italic:
r.italic = True
document = Document()
document.add_heading('Document Title', 0)
add_text([
Text('Text ', bold=True, italic=True),
Text('Text2', bold=False, italic=True)
], align='center')
add_text([
Text('Text ', bold=True, italic=True),
Text('Text2', bold=False, italic=True)
])
document.save('demo.docx')
I am trying to change the formatting for multiple paragraphs using Python's python-docx module.
from docx import Document
from docx.shared import Pt
from docx.shared import Inches
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.section import WD_ORIENTATION
from content import report_content, provinces, report_date, introduction, intro_content
alignment_dict = {'justify': WD_PARAGRAPH_ALIGNMENT.JUSTIFY,
'center': WD_PARAGRAPH_ALIGNMENT.CENTER,
'centre': WD_PARAGRAPH_ALIGNMENT.CENTER,
'right': WD_PARAGRAPH_ALIGNMENT.RIGHT,
'left': WD_PARAGRAPH_ALIGNMENT.LEFT}
orientation_dict = {'portrait': WD_ORIENTATION.PORTRAIT,
'landscape': WD_ORIENTATION.LANDSCAPE}
document = Document()
def change_orientation(orientation='portrait', set_left_margin=1.0, set_right_margin=1.0):
section = document.sections[-1]
new_width, new_height = section.page_height, section.page_width
section.orientation = orientation_dict[orientation]
section.page_width = new_width
section.page_height = new_height
section.left_margin = Inches(set_left_margin)
section.right_margin = Inches(set_right_margin)
def add_logo(path, align):
document.add_picture(path, width=Inches(4.5), height=Inches(1.5))
last_paragraph = document.paragraphs[-1]
last_paragraph.alignment = alignment_dict[align]
def add_content(content, space_after, font_name='Arial', font_size=11, line_spacing=0, space_before=0,
align='justify', keep_together=True, keep_with_next=False, page_break_before=False,
widow_control=False, set_bold=False, set_italic=False, set_underline=False, set_all_caps=False):
paragraph = document.add_paragraph(content)
style = document.styles['Normal']
font = style.font
font.name = font_name
font.size = Pt(font_size)
font.bold = set_bold
font.italic = set_italic
font.all_caps = set_all_caps
font.underline = set_underline
paragraph_format = paragraph.paragraph_format
paragraph_format.alignment = alignment_dict.get(align.lower())
paragraph_format.space_before = Pt(space_before)
paragraph_format.space_after = Pt(space_after)
paragraph_format.line_spacing = line_spacing
paragraph_format.keep_together = keep_together
paragraph_format.keep_with_next = keep_with_next
paragraph_format.page_break_before = page_break_before
paragraph_format.widow_control = widow_control
def create_numbered_list():
pass
def add_subheading(subheading, level):
document.add_heading(subheading, level)
change_orientation(orientation='landscape', set_left_margin=0.5, set_right_margin=0.5)
add_logo('logo.png', 'center')
add_content(report_content, align='Center', space_before=40, space_after=20, line_spacing=1, font_name='Arial',
set_bold=True, set_all_caps=True)
add_content(provinces, align='Center', space_before=20, space_after=20, line_spacing=1, font_name='Arial',
set_bold=True, set_all_caps=True)
add_content(report_date, align='Center', space_before=20, space_after=20, line_spacing=1, font_name='Arial',
set_bold=True, set_all_caps=True)
document.add_page_break()
add_subheading(introduction, level=1)
add_content(intro_content, space_after=20, space_before=20)
document.save('demo.docx')
The problem is every time I add formatting to a new paragraph block via the add_content method the formatting for the older blocks gets changed as the formatting for the current block.
Why am I not being able to retain the formatting, why does it get reset to the formatting of the latest block?
Try this code. use add_style to add new style. document.styles['Normal'] is a system style
I test it ok
from docx.enum.style import WD_STYLE_TYPE
#.........................
def add_content(content, space_after, font_name='Arial', font_size=16, line_spacing=0, space_before=0,
align='justify', keep_together=True, keep_with_next=False, page_break_before=False,
widow_control=False, set_bold=False, set_italic=False, set_underline=False, set_all_caps=False,style_name=""):
paragraph = document.add_paragraph(content)
paragraph.style = document.styles.add_style(style_name, WD_STYLE_TYPE.PARAGRAPH)
font = paragraph.style.font
font.name = font_name
font.size = Pt(font_size)
font.bold = set_bold
font.italic = set_italic
font.all_caps = set_all_caps
font.underline = set_underline
paragraph_format = paragraph.paragraph_format
paragraph_format.alignment = alignment_dict.get(align.lower())
paragraph_format.space_before = Pt(space_before)
paragraph_format.space_after = Pt(space_after)
paragraph_format.line_spacing = line_spacing
paragraph_format.keep_together = keep_together
paragraph_format.keep_with_next = keep_with_next
paragraph_format.page_break_before = page_break_before
paragraph_format.widow_control = widow_control
add_content("1234", align='Center', space_before=40, space_after=20, line_spacing=1, font_name='Arial', font_size=16,
set_bold=True, set_all_caps=True,style_name ="Normal1")
add_content("12345", align='Center', space_before=20, space_after=20, line_spacing=1, font_name='Arial',font_size=14,
set_bold=True, set_all_caps=True,style_name ="Normal2")
Your problem is here:
style = document.styles['Normal']
font = style.font
A style applies to all paragraphs that have that style. It's a document global thing. So any change you make the style.font affect all paragraphs with that style (which is all your paragraphs in this case).
Make sure you read this page in the documentation and the one that follows it:
http://python-docx.readthedocs.io/en/latest/user/styles-understanding.html
Character formatting (e.g. bold, size, typeface) happens at the run level (below paragraph, a paragraph is composed of runs). So if you want to apply character formatting directly, as opposed to by using a style, you need to do it to each run.
Adding content to a paragraph by calling document.add_paragraph(content) places all that content in a single run. So a quick fix might be:
font = paragraph.runs[0].font
Might be worth a try. But probably also a good idea to spend a little time with the concepts parts of the documentation to understand the Word object model a bit better. It's pretty complex for what seems on the surface to be a simple thing. This page is a good place to start:
http://python-docx.readthedocs.io/en/latest/user/text.html
I'm generating PDF files through ReportLab, but i can't find any documentation on how to generate an index linking to the file pages. Does ReportLab support this type of feature, or is there any other solution ?
After a lot of time searching i came up with an anchor solution. Although i feel it was not the perfect solution for me, i hope it helps someone in need.
from reportlab.lib.styles import ParagraphStyle
from reportlab.pdfbase.pdfmetrics import registerFont
from reportlab.platypus import Paragraph, PageBreak, SimpleDocTemplate, Spacer
registerFont(TTFont('Calibri', 'Calibri.ttf')) # Just some font imports
registerFont(TTFont('Calibri-Bold', 'calibrib.ttf'))
pH = ParagraphStyle(name = 'Header', fontName = 'Calibri-Bold', fontSize = 13, leftIndent = 20, firstLineIndent = -20, spaceBefore = 10, leading = 16)
sH = ParagraphStyle(name = 'SubHeader', fontName = 'Calibri', fontSize = 12, leftIndent = 40, firstLineIndent = -20, spaceBefore = 5, leading = 16)
doc = SimpleDocTemplate('Reports\\PDFname.pdf')
story = [Spacer(1, 2 * inch)]
story.append(Paragraph('<a href = page3.html#0>1. First Title</a>', pH)) # Linking the anchor to reference 0
story.append(Paragraph('<a href = page3.html#1>1.1. First Subtitle</a>', sH)) # Linking the anchor to reference 1
story.append(PageBreak())
story.append(Paragraph('<a name = page3.html#0></a> 1. First Title', pH)) # Creating anchor with reference 0
story.append(Paragraph('<a name = page3.html#1></a><br/> 1.1. First Subtitle', style)) # Creating anchor with reference 1
doc.build(story)