Python Docx line spacing for specific paragraph - python-3.x

Having looked through the docs, I am trying to figure out how to apply line spacing to a single paragraph, but it appears that any line spacing can only be done on a global scale using styles. Is there a way to isolate specific paragraphs while leaving the rest of the document as normal?
like this:
import docx
from docx.enum.text import WD_LINE_SPACING
text = 'Lorem ipsum...'
doc = Document()
para = doc.add_paragraph('text')
para.line_spacing = WD_LINE_SPACING.ONE_POINT_FIVE
The above code does not work of course and I can only guess that it is because line_spacing is a style level formatting. The other point about trying to localise this without doing styles is the portability of the document once built, if you cut and paste anything from one doc to another that may have been emailed to another computer runs the risk of reverting to the "Normal" style of the other machine. This can be prevented by not using document level styles (it's a nasty work around, but that is a word issue not a docx one.)

Line spacing is explained in the documentation here:
https://python-docx.readthedocs.io/en/latest/user/text.html#line-spacing
The short answer is you need to access the ParagraphFormat object on each paragraph and use .line_spacing_rule for that:
paragraph_format = paragraph.paragraph_format
paragraph_format.line_spacing_rule = WD_LINE_SPACING.ONE_POINT_FIVE

Yes, the above answer is for a specific paragraph.
If you want to configure for all the paragraphs in the document, you can do this.
document = Document()
style = document.styles['Normal']
style.paragraph_format.line_spacing = 0.5

Related

XWiki AppWithinMinutes add custom velocity script on display

I am new to XWiki and not a Java Developer. I would like to develop a simple AppWithinMinutes app (Let us call it ServerCatalog) for a list of servers with their properties like OS, Environment, etc.. That is all doable. I can develop that from AppWithinMinites UI.
I also have developed a macro which lists all pages by tags.
Now for example, when Someone creates an entry in my ServerCatalog say SERVERD56 Where D stands for Development environment.
when we display that Entry, I also want to execute my macro that I developed so that it can list all pages that matches the tag SERVERX56.
Note that I replaced D with X So before executing macro, I want to manipulate that page title and remove Environment prefix (in this case D for Development Environment) with X.
I hope it is clear of what I want to accomplish. Please let me know if it is unclear.
If someone can assist me on doing it, I will truly appreciate that.
EDITS:
As suggested by Eduard Moraru, I tried following things:
I have created a custom macro called "PageListByTag".
Since python has more control over string operations, I added following at the end of ServerCatalogSheet
.
.
.
.
{{/html}}
{{/velocity}}
{{python}}
title = document.getTitle()
newTitle = title[:6] + "X" + title[6+1:]
print(newTitle)
{{/python}}
There are several problems with it..
my html tag is already ended. I can't inject any new content in it anymore
I can't add python code inside velocity tags as nested scripting is not allowed by XWiki
I still don't know how to call my macro inside python code if I want to use python
If I can replace 6th character in a string using velocity, then everything works. I can use macro inside velocity script since it is within that html boundaries.
As far as I understand, you want to customize the "sheet" of the application which is used when displaying an application entry.
If you have a look a the documentation's section on customization, you get a lot of starting points on where you should be looking:
https://extensions.xwiki.org/xwiki/bin/view/Extension/App%20Within%20Minutes%20Application#HCustomization
This line would be interesting (but also the above links on how XWiki applications work):
The sheet, which is used to display and edit application entries (e.g. HolidaySheet)
In your case, it the document to customize (edit in wiki syntax mode) should be ServerCatalog.Code.ServerCatalogSheet
Inside that document, you have code automatically generated by AWM to which you can add a call to your macro.
## AWM generated code...
...
## Customization:
{{displayAssociatedPages /}}
Then, inside this macro (called displayAssociatedPages, in this example), you could do something like:
{{velocity}}
#set ($title = $doc.title)
## OR #set ($title = $doc.name), depending if your pages have titles
#if ($title.startsWith('SERVERD'))
#set ($tag = $title.replaceFirst('SERVERD', 'SERVERX'))
##
## We can reuse and customize this snippet: https://snippets.xwiki.org/xwiki/bin/view/Extension/Display%20pages%20with%20a%20specific%20tag/
##
#set ($references = $xwiki.tag.getDocumentsWithTag($tag))
#foreach($reference in $references)
#set ($document = $xwiki.getDocument($reference))
#set ($label = $document.getTitle())
[[$label>>$reference]]
#end
#end
{{/velocity}}
API documentation and more info at https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/API/
Also, you should understand that once you customize an AWM application, you should be careful when editing it with AWM itself. For example, if you add a new field, AFAIK, you risk having the customizations done to your sheet, as in the above example, overwritten, so you should recover them from document history and re-apply them.

Add a set of images after a specific text in a word file with Python docx

I have a set of images in a folder and I am trying to insert them into a word file. Each image has a number as an indicator and I want to insert them right after a specific tag I put in the document. The thing is Pyton's docx is only adding the images at the end of the document.
This is the portion of the code where I add the images:
for par in doc.paragraphs:
tag='[First set of images]')
if tag in par.text:
doc.add_picture(alt_file+'\\'+imgs[1],width=Cm(22.51))
doc.save(docs[1])enter code here
If the number is in a paragraph by itself, you can add a picture in a run following the text (but still in the same paragraph) like this:
if tag in paragraph.text:
run = paragraph.add_run()
run.add_picture("image.png", ...)
The details of the Run.add_picture() call are in the API documentation here:
https://python-docx.readthedocs.io/en/latest/api/text.html#run-objects

sphinx, rinohtype: Page Break after every section

I want a page break after every chapter and every section.
We can get page breaks in restructured text, anywhere we want using:
.. raw::pdf
PageBreak
The good thing is this works both with rst2pdf as well as rinohtype. However, the advantage with rinohtype is we can achieve the same without adding the above code manually after every section using stylesheets.
I am just not sure how we can do that using stylesheets, can anyone help?
Using a custom style sheet, you can force page breaks before arbitrary sections by setting the page_break style attribute (in the upcoming 0.5.0 release, page_break can be set on any flowable, not just sections).
To insert a page break at an arbitrary point:
Indicate where to insert the page break:
or using the class directive (or rst-class in Sphinx) before a body element, or
assign a class to a directive by setting the :class: attribute
Define a style with a selector matching the class name. This is achieved by means of the has_class selector attribute.
The page break will be inserted before the corresponding element.
Here's an example, assuming you're using rinohtype 0.4.3.dev1 or later:
Your reStructuredText file:
.. image:: images/screenshot.png
:class: page-break
A regular paragraph.
.. rst-class:: page-break
This paragraph will trigger a page break.
Your custom style sheet:
[page-break-paragraph : Paragraph(has_class="page-break")]
base = default
page_break = any
[page-break-image : Image(has_class="page_break")]
base = image
page_break = any
Note that the newly defined styles will also determine the styling of the page-breaking element. To style them like other elements in the document, you need to set their base style to the default style. Refer to the style log to figure out which styles these are.
See issue #186 for some more details about page breaks in reStructuredText and rinohtype.

Converting a string automatically into a link to a pdf document

I've done some looking around in here and on the internet and it doesnt seem super obvious, but my question is can python using tkinter be used to automatically convert a text string into a link that loads a pdf from a certain direction
e.g. data '12345 Issue A' pops up in a text widget and is automatically converted to a link that when clicked opens up a pdf document.
Can this or can it not be done ?
In this case I'm wanting to be able to click 1931-125, 699-126 and 1851-127 and have each open up a pdf file of the same name. This is being used in a manufacturing environment and allows an assembler to click the fields and have all the documents they need to build a certain item
First off to apply formatting to parts of a Text widget you will need to understand about tags, in most cases you can probably just use the phrase of the link (ABC123) just remember that:
The name of a tag can be any string that does not contain white space or periods.
once you have a tag for the link there are two parts:
Formatting the tag to look and react like a link.
Applying the tag to the phrases in text.
The first one is really simple if you just want it to be blue and underlined and respond to being clicked:
def format_link(text_widget,tag,command):
text_widget.tag_config(tag,foreground="blue",underline=1)
text_widget.tag_bind(tag,"<Button-1>",command)#remember that the command will need to take an event argument
Although this could get more complicated if you want the cursor to change when hovering over or colour to change after clicking etc.
The second part is to apply this tag to the text automatically which I'm assuming means parse the text after it is inserted into the widget. This is also very simple by putting this answer in a loop so that it checks for every occurrence of the phrase:
def apply_tag(text_widget,phrase,tag,regexp=False):
countVar = tk.IntVar(text_widge)
idx = "1.0"
while idx:
idx = text_widget.search(phrase,idx, stopindex = "end",
count = countVar, regexp = regexp)
if idx:
end_idx = "%s + %sc" %(idx, countVar.get())
text_widget.tag_add(tag, idx, end_idx)
idx = end_idx
Then all that is left is defining the way to open the file in another program and then calling the two above functions, using os.system("open"...) to open files it could be as simple as:
def make_link(text,phrase,file_to_open):
def callback(event=None):
os.system("open %r"%file_to_open)#there are better ways of handling this
apply_tag(text,phrase,phrase)#uses phrase as tag
format_link(text,phrase,callback)
Although you might want to look at answers here or it's duplicate for alternatives for opening files.
after inserting the text into the widget, assuming you have some sort of list of phrases to turn into links, you can just loop over the phrases and call make_link for each one:
phrases = {"1931-125", "699-126", "1851-127"}
for s in phrases:
make_link(TEXT_W, s, s+".pdf") #make a link to same name with .pdf added to end.

Split String on tags into multiple Textboxes

I do not knot where to search anymore for a solution.
I have a string which contains tags "< p >" and "< /p >", as well as "< h1>" and "< /h1>" for headers, and "< a>< /a>" for links. The string is passed via app.current to a second page, when i set it as source of a textblock I see my whole string.
Now my Problem:
I want to create a new TextBlock on every "< p>", which contains the text until "< /p>". Same for the headers, as I want to style them differently. The links I want to see in a list.
I tried several things, but found no working solution. My last try was to work with this http://www.eugenedotnet.com/2011/04/binding-text-containing-tags-to-textblock-inlines-using-attached-property-in-silverlight-for-windows-phone-7/. I was not able to change this for my needs.
I wanted to create substrings from my string, and for each substring a new run with/or a new TextBlock. Did not figure it out.
I really do not have any ideas left for this. Anyone any idea?
I'd recommend using HtmlAgilityPack to parse the HTML.
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(yourString);
string header = doc.DocumentNode.SelectSingleNode("h1").InnerText;
List<string> paragraphs = doc.DocumentNode.SelectNodes("p")
.Select(p => p.InnerText).ToList();
The simplest way to get HtmlAgilityPack for WP7 is to install NuGet, right click your References and select "Manage NuGet Packages" and then search "Online" for HtmlAgilityPack.
To expand slightly on Richard Szalay's answer, the version of the HTML Agility Pack on NuGet doesn't seem to include the WP7 specific implementation that was added. In this question there is a reference to the HAPPhone version which can be downloaded from the HTML AGility Pack project page, and works very well on the phone.
Unfortunately, you'll have to download the source and build it yourself / add the reference manually. I guess the NuGet version will be updated in time, but when I did this last week it was the only way.

Resources