I need to parse through a file path in Windows, make sure I have provided a csv file. I have tested the regex in an online regex generator and made sure it matches the text I provide it.
Program.tx:
Program:
'begin'
commands*=Command
'end'
;
Command:
Test | Configuration
;
Test:
'test'
;
Configuration:
'configuration' location=/[a-zA-Z:a-zA-Z\\]+(\.csv$)/
;
test.dsl:
begin
configuration C:\Users\me\Desktop\test.csv
end
program.py:
from textx import metamodel_from_file
from Input import Input
class Robot(object):
def __init__(self):
self.input_location = None
def setInput(self, location):
self.input = Input(location)
def interpret(self, model):
for c in model.commands:
if c.__class__.__name__ == "Configuration":
self.setInput(c.location)
robot_mm = metamodel_from_file('Program.tx')
robot_model = robot_mm.model_from_file('test.dsl')
robot = Robot()
robot.interpret(robot_model)
Once I use Robot.interpret(), I cannot parse through the provided filepath
textx.exceptions.TextXSyntaxError: None:2:19: error: Expected '[a-zA-Z:a-zA-Z\\]+(\.csv$)' at position c:\Users\me\Desktop\test.dsl:(2, 19) => 'on *C:\Users\me\Des'.
After spending a day on the problem, turns out textX doesn't like the anchor character - '$'.
Related
I want to replace variables in a .docx with arguments python. I got the script for replacement working but I don't know how to correctly print the arguments. I run my python script like:
$ python var-replace.py cat fish dog
var-replace.py looks like:
`
import sys
arg1, arg2, arg3 = sys.argv[1], sys.argv[2], sys.argv[3]
from docx import Document
doc = Document('test.docx')
replacements = {
'${replace_me_1}': "print(arg1)",
'${replace_me_2}': "file.writelines(arg2)",
'${replace_me_3}': "(arg3)",
}
for paragraph in doc.paragraphs:
for key in replacements:
paragraph.text = paragraph.text.replace(key, replacements[key])
doc.save('test.docx')
input of test.docx:
`
${replace_me_1}
${replace_me_2}
${replace_me_3}
output of test.docx after running var-replace.py:
`
print(arg1)
file.writelines(arg2)
(arg3)
Expected output:
`
cat
fish
dog`
How do i correctly replace the arguments to the .docx?
Additional question:
How do I save the docx as sys.argv[3].docx (dog.docx)?
Are you sure that you need to pass the values in as strings instead of calling them?
import sys
arg1, arg2, arg3 = sys.argv[1], sys.argv[2], sys.argv[3]
from docx import Document
doc = Document('test.docx')
#current - wrong approach
replacements = {
'${replace_me_1}': "print(arg1)",
'${replace_me_2}': "file.writelines(arg2)",
'${replace_me_3}': "(arg3)",
}
#possible change
replacements = {
'${replace_me_1}': str(arg1),
'${replace_me_2}': arg2,
'${replace_me_3}': arg3,
}
for paragraph in doc.paragraphs:
for key in replacements:
paragraph.text = paragraph.text.replace(key, replacements[key])
doc.save('test.docx')
I am writing a python program that open a docx file and writing text into it. using "aspose.words"
and I have two problems:
I have a problem that when I open a file its starting with the sentence
"Evaluation Only. Created with Aspose.Words. Copyright 2003-2021 Aspose Pty Ltd."
and I want to delete that line after I creating the file (I can delete it manually so it's deletable)
my second problem is when I am using "font.bold = True" on an english text it's working just fine but when I am using it on an text that in other language its doesen't work.
Someone know how can I solves those two problems (it's the first time I am using "aspose.words")
here is my code:
import aspose.words as aw
def main():
doc = aw.Document()
builder = aw.DocumentBuilder(doc)
writeDest(1, builder)
doc.save("out.docx")
def writeDest(designation, builder):
font = builder.font
font.size = 12
font.bold = True
font.name = "David"
paragraphFormat = builder.paragraph_format
paragraphFormat.alignment = aw.ParagraphAlignment.RIGHT
label = 'ייעוד: ' + str(designation)
builder.write(label)
builder.write("\n")
font.bold = False
if designation == 1:
file = open('destenationTextFiles/1', encoding="utf8")
for word in file:
builder.write(word)
builder.write('\n')
font.bold = True
builder.write(':תיקון ')
builder.write("\n")
font.bold = False
file.close()
file = open("destenationTextFiles/fixed1", encoding="utf8")
for word in file:
builder.write(word)
file.close()
if __name__ == "__main__":
main()
This message indicates you are using Aspose.Words in evaluation mode. Please see the following article to learn more about evaluation version limitations of Aspose.Words.
To test Aspose.Words for Python without these limitations you can request a temporary 30 days license.
To format right-to-left text you should use bidi font properties. For example see the following python code:
import aspose.words as aw
def main():
doc = aw.Document()
builder = aw.DocumentBuilder(doc)
# Define a set of font settings for left-to-right text.
builder.font.name = "Courier New"
builder.font.size = 16
builder.font.italic = False
builder.font.bold = False
builder.font.locale_id = 1033
# Define another set of font settings for right-to-left text.
builder.font.name_bi = "David"
builder.font.size_bi = 24
builder.font.italic_bi = True
builder.font.bold_bi = True
builder.font.locale_id_bi = 1037;
# We can use the Bidi flag to indicate whether the text we are about to add
# with the document builder is right-to-left. When we add text with this flag set to true,
# it will be formatted using the right-to-left set of font settings.
builder.font.bidi = True
builder.write("ברוך הבא")
# Set the flag to false, and then add left-to-right text.
# The document builder will format these using the left-to-right set of font settings.
builder.font.bidi = False
builder.write(" Hello world!")
doc.save("C:\\Temp\\Font.Bidi.docx")
if __name__ == "__main__":
main()
I'm using mathjax-node to try to convert mathjax code into an SVG. Currently, the code I have set up here is this:
const mathjax = require("mathjax-node");
process.stdin.on("data", data => {
mathjax.typeset({
math: data.slice(1),
format: [...data][0] == "Y" ? "inline-TeX" : "TeX",
svg: true
}).then(data => {
process.stdout.write(data.svg + String.fromCodePoint(0));
});
});
Which takes in input and the first character determines if it's inline or not and everything else is the code. It's used by a python file like this:
# -*- coding: utf-8 -*-
from subprocess import *
from pathlib import Path
cdir = "/".join(str(Path(__file__)).split("/")[:-1])
if cdir:
cdir += "/"
converter = Popen(["node", cdir + "mathjax-converter.js"], stdin = PIPE, stdout = PIPE)
def convert_mathjax(mathjax, inline = True):
converter.stdin.write(bytes(("Y" if inline else "N") + mathjax, "utf-8"))
converter.stdin.flush()
result = ""
while True:
char = converter.stdout.read(1)
if not char: return ""
if ord(char) == 0:
return result
result += char.decode("utf-8")
So convert_markdown is the function that takes the code and turns it into the SVG. However, when I try to render the output just using data:text/html,<svg>...</svg>, it gives this error in the console:
Error: <path> attribute d: Expected number, "…3T381 315T301241Q265 210 201 149…".
Using MathJax client-side with the _SVG config option works fine, so how do I resolve this?
I can confirm that there is an error in that SVG path. The T command is supposed to have two coordinate parameters. But there is one in the middle there that doesn't.
T 381 315 T 301241 Q ...
is probably supposed to be:
T 381 315 T 301 241 Q ...
Either there is a bug in the mathjax SVG generator, or something else in your code is accidentally stripping random characters.
I'm trying read and parse a CSV file in LibreOffice Calc. I need to show text in order to debug my logic, and the first thing I found was this. Annoyingly, it duplicates functionality that's built into OOo Basic. The first implementation tries to use a non-existent function; the second one works if I invoke it directly (using TestMessageBox from the Tools menu), but when I include it from my pythonpath directory I get an error:
com.sun.star.uno.RuntimeExceptionError during invoking function main
in module
file:///C:/path/to/test.py
(: 'module' object has no attribute
'MessageBox' C:\path\to\test.py:34
in function main() [msgbox.MessageBox(parentwin, message, 'Title')]
C:\Program Files (x86)\LibreOffice 5\program\pythonscript.py:870 in
function invoke() [ret = self.func( *args )] )
Why is there no attribute MessageBox?
I'm invoking it like this:
import msgbox
def main():
doc = XSCRIPTCONTEXT.getDocument()
parentwin = doc.CurrentController.Frame.ContainerWindow
message = "Message"
msgbox.MessageBox(parentwin, message, 'Title')
return
And here's pythonpath/msgbox.py:
import uno
from com.sun.star.awt.MessageBoxButtons import BUTTONS_OK, BUTTONS_OK_CANCEL, BUTTONS_YES_NO, BUTTONS_YES_NO_CANCEL, BUTTONS_RETRY_CANCEL, BUTTONS_ABORT_IGNORE_RETRY
from com.sun.star.awt.MessageBoxButtons import DEFAULT_BUTTON_OK, DEFAULT_BUTTON_CANCEL, DEFAULT_BUTTON_RETRY, DEFAULT_BUTTON_YES, DEFAULT_BUTTON_NO, DEFAULT_BUTTON_IGNORE
from com.sun.star.awt.MessageBoxType import MESSAGEBOX, INFOBOX, WARNINGBOX, ERRORBOX, QUERYBOX
def TestMessageBox():
doc = XSCRIPTCONTEXT.getDocument()
parentwin = doc.CurrentController.Frame.ContainerWindow
s = "This a message"
t = "Title of the box"
res = MessageBox(parentwin, s, t, QUERYBOX, BUTTONS_YES_NO_CANCEL + DEFAULT_BUTTON_NO)
s = res
MessageBox(parentwin, s, t, "infobox")
# Show a message box with the UNO based toolkit
def MessageBox(ParentWin, MsgText, MsgTitle, MsgType=MESSAGEBOX, MsgButtons=BUTTONS_OK):
ctx = uno.getComponentContext()
sm = ctx.ServiceManager
sv = sm.createInstanceWithContext("com.sun.star.awt.Toolkit", ctx)
myBox = sv.createMessageBox(ParentWin, MsgType, MsgButtons, MsgTitle, MsgText)
return myBox.execute()
g_exportedScripts = TestMessageBox,
The package name msgbox is already used in UNO. See msgbox.MsgBox. Choose a different name for your module instead, such as mymsgbox.py. Even better, move it to a package (subdirectory) inside pythonpath, such as mystuff.msgbox.MessageBox.
As a matter of fact, I tried msgbox.MsgBox just now and it seemed like it could be useful:
import msgbox
def main():
message = "Message"
myBox = msgbox.MsgBox(XSCRIPTCONTEXT.getComponentContext())
myBox.addButton("oK")
myBox.renderFromButtonSize()
myBox.numberOflines = 2
myBox.show(message,0,"Title")
I have a C header file which contains a series of classes, and I'm trying to write a function which will take those classes, and convert them to a python dict. A sample of the file is down the bottom.
Format would be something like
class CFGFunctions {
class ABC {
class AA {
file = "abc/aa/functions"
class myFuncName{ recompile = 1; };
};
class BB
{
file = "abc/bb/functions"
class funcName{
recompile=1;
}
}
};
};
I'm hoping to turn it into something like
{CFGFunctions:{ABC:{AA:"myFuncName"}, BB:...}}
# Or
{CFGFunctions:{ABC:{AA:{myFuncName:"string or list or something"}, BB:...}}}
In the end, I'm aiming to get the filepath string (which is actually a path to a folder... but anyway), and the class names in the same class as the file/folder path.
I've had a look on SO, and google and so on, but most things I've found have been about splitting lines into dicts, rather then n-deep 'blocks'
I know I'll have to loop through the file, however, I'm not sure the most efficient way to convert it to the dict.
I'm thinking I'd need to grab the outside class and its relevant brackets, then do the same for the text remaining inside.
If none of that makes sense, it's cause I haven't quite made sense of the process myself haha
If any more info is needed, I'm happy to provide.
The following code is a quick mockup of what I'm sorta thinking...
It is most likely BROKEN and probably does NOT WORK. but its sort of the process that I'm thinking of
def get_data():
fh = open('CFGFunctions.h', 'r')
data = {} # will contain final data model
# would probably refactor some of this into a function to allow better looping
start = "" # starting class name
brackets = 0 # number of brackets
text= "" # temp storage for lines inside block while looping
for line in fh:
# find the class (start
mt = re.match(r'Class ([\w_]+) {', line)
if mt:
if start == "":
start = mt.group(1)
else:
# once we have the first class, find all other open brackets
mt = re.match(r'{', line)
if mt:
# and inc our counter
brackets += 1
mt2 = re.match(r'}', line)
if mt2:
# find the close, and decrement
brackets -= 1
# if we are back to the initial block, break out of the loop
if brackets == 0:
break
text += line
data[start] = {'tempText': text}
====
Sample file
class CfgFunctions {
class ABC {
class Control {
file = "abc\abc_sys_1\Modules\functions";
class assignTracker {
description = "";
recompile = 1;
};
class modulePlaceMarker {
description = "";
recompile = 1;
};
};
class Devices
{
file = "abc\abc_sys_1\devices\functions";
class registerDevice { recompile = 1; };
class getDeviceSettings { recompile = 1; };
class openDevice { recompile = 1; };
};
};
};
EDIT:
If possible, if I have to use a package, I'd like to have it in the programs directory, not the general python libs directory.
As you detected, parsing is necessary to do the conversion. Have a look at the package PyParsing, which is a fairly easy-to-use library to implement parsing in your Python program.
Edit: This is a very symbolic version of what it would take to recognize a very minimalistic grammer - somewhat like the example at the top of the question. It won't work, but it might put you in the right direction:
from pyparsing import ZeroOrMore, OneOrMore, \
Keyword, Literal
test_code = """
class CFGFunctions {
class ABC {
class AA {
file = "abc/aa/functions"
class myFuncName{ recompile = 1; };
};
class BB
{
file = "abc/bb/functions"
class funcName{
recompile=1;
}
}
};
};
"""
class_tkn = Keyword('class')
lbrace_tkn = Literal('{')
rbrace_tkn = Literal('}')
semicolon_tkn = Keyword(';')
assign_tkn = Keyword(';')
class_block = ( class_tkn + identifier + lbrace_tkn + \
OneOrMore(class_block | ZeroOrMore(assignment)) + \
rbrace_tkn + semicolon_tkn \
)
def test_parser(test):
try:
results = class_block.parseString(test)
print test, ' -> ', results
except ParseException, s:
print "Syntax error:", s
def main():
test_parser(test_code)
return 0
if __name__ == '__main__':
main()
Also, this code is only the parser - it does not generate any output. As you can see in the PyParsing docs, you can later add the actions you want. But the first step would be to recognize the what you want to translate.
And a last note: Do not underestimate the complexities of parsing code... Even with a library like PyParsing, which takes care of much of the work, there are many ways to get mired in infinite loops and other amenities of parsing. Implement things step-by-step!
EDIT: A few sources for information on PyParsing are:
http://werc.engr.uaf.edu/~ken/doc/python-pyparsing/HowToUsePyparsing.html
http://pyparsing.wikispaces.com/
(Particularly interesting is http://pyparsing.wikispaces.com/Publications, with a long list of articles - several of them introductory - on PyParsing)
http://pypi.python.org/pypi/pyparsing_helper is a GUI for debugging parsers
There is also a 'tag' Pyparsing here on stackoverflow, Where Paul McGuire (the PyParsing author) seems to be a frequent guest.
* NOTE: *
From PaulMcG in the comments below: Pyparsing is no longer hosted on wikispaces.com. Go to github.com/pyparsing/pyparsing