I'm very new to Python and Sublime Text API dev... so this may be easy?
I want to display the contents of a file (that sits next to the currently open file) to a new panel window.
I can create a new panel no problem and get it to display a string using
def newLogWindow(self, output):
window = self.view.window()
new_view = window.create_output_panel("log")
new_view.run_command('erase_view')
new_view.run_command('append', {'characters': output})
window.run_command("show_panel", {"panel": "output.log"})
sublime.status_message('Metalang')
pass
But what I need is a function to get contents of file to pass to that function.
content = xxxx.open_file("filename.txt")
// somehow get contents of this file?
// pass it to log window
self.newLogWindow(content);
Thanks for your help!
In Sublime Text, the built in API to open a file is tied to the Window and will return a View that corresponds to a tab. In your case, you want to update a panel (an existing View that doesn't relate to a tab) with the contents of the file, so the Sublime Text API can't be used for this.
Instead you can do it directly in Python using the open method:
with open('filename.txt', 'r') as myfile:
content = myfile.read()
self.newLogWindow(content)
Related
I am building an internal plugin for Sublime Text 3 to automate some changes we need done in our HTML.
I'm close to finishing it so we can start using it but I just have one small issue I can't seem to find a solution for.
The plugin will search for some specific HTML code, save them in a file and then modify the code in the view to reference some text in a json file. Then the plugin will open a new view and paste the contents of the file we saved some code in step 1. After which, I need to do some formatting in the new view (replace commas, quotes and brackets with a new line) and then run another internal sublime command in the new view.
The issue is after replacing the commas, quotes and brackets with a new line, the new view changes to an "Instant File Search" which messes with how the view runs the next command and inserts some garbage characters.
Example of the code:
#Open new tab and paste the copied subheads
newView = self.view.window().new_file(syntax="HTML.sublime-syntax")
newView.insert(edit, 0, json.dumps(sections))
# Clear any current selections in the new view
newView.sel().clear()
# Remove quotes, commas and square brackets and separate into new lines
q = newView.find_all(r"(\x{0022}\,\s\x{0022})|(\[\x{0022})|(\x{0022}\])")
for region in reversed(q):
newView.sel().add(region)
newView.replace(edit, region, "\n")
# Clear any current selections in the new view
newView.sel().clear()
q = newView.find_all("{% r")
for region in reversed(q):
newView.sel().add(region)
newView.replace(edit, region, "<p>{% r")
# Clear any current selections in the new view
newView.sel().clear()
q = newView.find_all("endreplace %}")
for region in reversed(q):
newView.sel().add(region)
newView.replace(edit, region, "endreplace %}</p>")
This is what it outputs in the new view:
If I click undo, I get the expected output which seems to mean sublime does something extra after running the last find_all code.
I haven't found anything online regarding this issue so I'm unable to try things to fix this.
Does anyone have an idea on how I should proceed?
P.S. One possible solution is to manually open a new view and run some commands but I'm trying to do all of that in 1 step using my plugin.
I'm new to python and I'm trying to create a script to open an existing .svg file, change the text/font/colour/size, and then save it as a separate .svg
I've managed to create another script using svgwrite but this can only make new files instead of editing existing ones.
I've had a look at a few other threads suggesting using the inkscape extension inkex.py but I can't figure out how to write anything working with this.
I've also tried lxml but I don't really understand what I'm doing with this. From everything I found I know I have to parse the .svg and from this I got the below code but this seems to be a dead end as the result is blank
import lxml.etree as ET
xml = ET.parse('C:\\Users\\Admin\\Desktop\\Test2.svg')
svg = xml.getroot()
print(svg)
print(svg.findall(".//{Element {http://www.w3.org/2000/svg}svg at 0x3e107a8"))
--Edit
In case anyone is trying to do something similar I did some more digging and found the best way to do it for my purpose was to open the svg, replace the string where it was needed and write to file, e.g.
Change = open(/files/file.svg, "rt")
data = change.read()
data = data.replace('original text', 'new text')
Change.close()
Change = open(/files/file.svg "wt")
Change.write(data)
Change.close()
I am using pypdf2 to highlight text in a particular page in Pdf files.Hence,I get only a single page with higlighted text as an output.Now,I want to replace this page in the original pdf file.
I have also tried "search=" parameter from abode to highlight in the same file itself.But,It is not working.
I am new to working with PDFs.Sorry,If the question sounded a bit naive.
Get a word processor or page layout software. Convert PDF to format your software can read. Edit document. Write new PDF.
Anything else sounds nefarious. Nobody should help you do it any other way.
To replace a page in a given file you can try do the following approach:
Get the page (the object) that you wanna modify/replace
Change it (the PyPDF2 return the object itself instead a getter, so, you can change it).
In the code below, I'm adding a "water mark" in my document:
tmp_name = "__tmp.pdf"
output_file = PdfFileWriter()
with open(inFile, 'rb') as f:
# Read the pdf (create a pdf stream)
pdf_original = PdfFileReader(f, strict=False)
# put all buffer in a single file
output_file.appendPagesFromReader(pdf_original)
# create new PDF with water mark
WaterMark._page(fixPage, tmp_name)
# Open the created pdf
with open(tmp_name, 'rb') as ftmp:
# Read the temp pdf (create a pdf stream obj)
temp_pdf = PdfFileReader(ftmp)
for p in range(startPage, startPage+pages):
original_page = output_file.getPage(p)
temp_page = temp_pdf.getPage(0)
original_page.mergePage(temp_page)
# write result
if output_file.getNumPages():
# newpath = inFile[:-4] + "_numbered.pdf"
with open(outFile, 'wb') as f:
output_file.write(f)
os.remove(tmp_name)
My answer is based on this and this
The pdf that I've used
Above you can see the second page (edited page) in my document.
I use python-pptx v0.6.2 to generate powerpoint. I read a exist powerpoint into BytesIO, then do some modification and save it. I can download the file successfully, and I'm sure the content can be write into the file. But when I open the powerpoint, it will popup a error message "Powerpoint found a problem with content in foo.pptx. Powerpoint can attempt to repair the presatation.", then I have to click "repair" button, the powerpoint will display as "repaired" mode. My Python version is 3.5.2 and Django version is 1.10. Below is my code:
with open('foo.pptx', 'rb') as f:
source_stream = BytesIO(f.read())
prs = Presentation(source_stream)
first_slide = prs.slides[0]
title = first_slide.shapes.title
subtitle = first_slide.placeholders[1]
title.text = 'Title'
subtitle.text = "Subtitle"
response = HttpResponse(content_type='application/vnd.ms-powerpoint')
response['Content-Disposition'] = 'attachment; filename="sample.pptx"'
prs.save(source_stream)
ppt = source_stream.getvalue()
source_stream.close()
response.write(ppt)
return response
Any help is appreciate, thanks in advance!
It looks like you've got problems with the IO.
The first three lines can be replaced by:
prs = Presentation('foo.pptx')
Placing the file into a memory-based stream just uses unnecessary resources.
On the writing, you're writing to that original (unnecessary) stream, which is dicey. I suspect that because you didn't seek(0) that you're appending onto the end of it. Also it's conceptually more complicated to deal with reuse.
If you use a fresh BytesIO buffer for the save I think you'll get the proper behavior. It's also better practice because it decouples the open, modify, and save, which you can then factor into separate methods later.
If you eliminate the first BytesIO you should just need the one for the save in order to get the .pptx "file" into the HTTP response.
I am trying to save the contents of a Text Editor as a pdf file. The text Editor has been made using PyQt (i didn't make the text Editor), i got the code of the text editor from here. I have done some changes to the editor but that wont be a problem.
After some initial research i found that i need to use ReportLab to publish a pdf file.But i can't find a way to do this .
Does anyone know how this could be accomplished ?
The source code for the Text Editor already has a PDF method, but it is unused, and possibly won't work properly as it stands.
A basic re-write of the method that should work on all platforms, would look like this:
def SavetoPDF(self):
filename = QtGui.QFileDialog.getSaveFileName(self, 'Save to PDF')
if filename:
printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
printer.setPageSize(QtGui.QPrinter.A4)
printer.setColorMode(QtGui.QPrinter.Color)
printer.setOutputFormat(QtGui.QPrinter.PdfFormat)
printer.setOutputFileName(filename)
self.text.document().print_(printer)
The only other thing you'll need is a menu item to run it, so in Main.initUI just add:
pdfAction = QtGui.QAction("Save to PDF", self)
pdfAction.setStatusTip("Save to PDF")
pdfAction.triggered.connect(self.SavetoPDF)
...
file.addAction(pdfAction)