Colorizing Text within Rich Tree - python

Im building some trees within Rich. However Im outputting obj repr() and also Python object details that Rich only seems to want to display if I pass the data to the tree branch as a string. i.e.
tree = Tree(str(type(root_obj)))
My question is this out can i colourize the output of my tree in Rich. For example if I pass a type to the tree without casting it to a string I get:
tree = Tree(type(root_obj))
...
rich.errors.NotRenderableError: Unable to render <class 'nornir.core.task.AggregatedResult'>; A str, Segment or object with __rich_console__ method is required
But not sure what console method to use here. Any help would be great. Thanks.

You can highlight text via a Rich highlighter. The ReprHighlighter will highlight the strings produces from most objects. Import it like this:
from rich.highlighter import ReprHighlighter
highlighter = ReprHighlighter()
Now you can highlight strings in the following way:
tree = Tree(highlighter(str(root_obj)))
Alternatively, you can use Rich's pretty printing capabilities via the rich.pretty.Pretty class:
from rich.pretty import Pretty
tree = Tree(Pretty(rich_obj))

Related

Find all occurrences of bytestrings in a python code snippet

I'm trying to parse python snippets, some of which contains bytestrings.
for example:
"""
from gzip import decompress as __;_=exec;_(__(b'\x1f\x8b\x08\x00\xcbYmc\x02\xff\xbd7i\xb3\xdaJv\xdf\xdf\xaf /I\xf9\xbar\xc6%\x81#\x92k\x9c)\x16I,b\x95Xm\x87\x92Z-$\xd0\x86\x16\x10LM~{N\x03\xd7\xc6\xd7\x9e%\xa9\xa9PE/\xa7\xcf\xbeuk\xd3\xacm\xdd"\x94\x1b\'\xa5\xda\x04"H\x17\xae\xe3t\xf4\xcdn\x03\xa9/&T>\x13\xdbu\g=\x9f\x13~\x11\xf6\x9b\xd7\x15~\xb2\xe7\xbc\xe6\xc2K\xb8\x18\x03\xfd|[\x7f\xe8\xb8I;\xf0\xf1\x93\xec\x83\x8eo15\x8dC\xfc\xc6I\xf1\xfd\xf5r\x8f\xeb\x0f\xd7\xc53#\xa8<_\xb2Py\xbe\xe1\xde\xff\x0fk&\x93\xa8V\x18\x00\x00'))
x = b"\x1f\x8b\x08"
y = "hello world"
"""
Is there a regex pattern I can use to correctly find those strings?
I have tried implementing a regex query myself, like so:
bytestrings= re.findall(r'b"(.+?)"', text) + re.findall(r"b\'(.+?)'", text)
I was expecting to receive an array
[b'\x1f\x8b\x08\x00\xcbYmc\x02\xff\xbd7i\xb3\xdaJv\xdf\xdf\xaf /I\xf9\xbar\xc6%\x81#\x92k\x9c)\x16I,b\x95Xm\x87\x92Z-$\xd0\x86\x16\x10LM~{N\x03\xd7\xc6\xd7\x9e%\xa9\xa9PE/\xa7\xcf\xbeuk\xd3\xacm\xdd"\x94\x1b\'\xa5\xda\x04"H\x17\xae\xe3t\xf4\xcdn\x03\xa9/&T>\x13\xdbu\g=\x9f\x13~\x11\xf6\x9b\xd7\x15~\xb2\xe7\xbc\xe6\xc2K\xb8\x18\x03\xfd|[\x7f\xe8\xb8I;\xf0\xf1\x93\xec\x83\x8eo15\x8dC\xfc\xc6I\xf1\xfd\xf5r\x8f\xeb\x0f\xd7\xc53#\xa8<_\xb2Py\xbe\xe1\xde\xff\x0fk&\x93\xa8V\x18\x00\x00', b"\x1f\x8b\x08"]
instead it returns an empty array.
This isn't a job for regular expressions, but for a Python parser.
import ast
code = """
...
"""
tree = ast.parse(code)
Now you can walk the tree looking for values of type ast.Constant whose value attributes have type bytes. Do this by defining a subclass of ast.NodeVisitor and overriding its visit_Constant method. This method will be called on each node of type ast.Constant in the tree, letting you examine the value. Here, we simply add appropriate values to a global list.
bytes_literals = []
class BytesLiteralCollector(ast.NodeVisitor):
def visit_Constant(self, node):
if isinstance(node.value, bytes):
bytes_literals.append(node.value)
BytesLiteralCollector().visit(tree)
The documentation for NodeVisitor is not great. Aside from the two documented methods visit and generic_visit, I believe you can define visit_* where * can be any of the node types defined in the abstract grammar presented at the start of the documentation.
You can use print(ast.dump(ast.parse(code), indent=4)) to get a more-or-less readable representation of the tree that your visitor will walk.

How Can I Extract Variables from a LaTeX Doc into a Python Dictionary So That I Can Pull it into Django?

I'm pretty new to Django and LaTeX so I'm hoping that someone out there has done something like this before:
I'm trying to create a Django app that can read a LaTeX file, extract all of the variables (things of this form: "\newcommand{\StartDate}{January 1, 2018}") and place them as key/value pairs into a dictionary that I can work with inside Django.
The idea is that each variable in the LaTeX file starts with a place holder value. I'll be building a dynamic form that uses the dictionary to create field/values and let's a user replace the place holder value with a real one. After a user has set all of the values, I'd like to be able to write those new values back into the LaTeX file and generate a pdf from it.
I've tried regular expressions but have run into trouble because some of the 'variables' will contain blocks of LaTeX like lists, for example. I've also looked at TexSoup which seems to be very promising but I haven't been able to totally figure out yet. Here is a section from the preamble of an example LaTeX file like the ones I'll be dealing with:
%% Project Name
\newcommand{\projectName}{Project Name}
%% Start and End dates
\newcommand{\startDate}{January 1, 2018}
\newcommand{\finDate}{December 31, 2018}
%% Name of User
\newcommand{\userName}{aUser}
% What tasks will be a part of this process?
\newcommand{\tasks}{
\begin{itemize}[noitemsep,topsep=0pt]
\item Planning of \projectName{} on \startDate{}
\item Construction of \projectName{}
\item Configuration of \projectName{} by \userName{} on \finDate{}
\end{itemize}
}
Using TexSoup, I'm able to pull the LaTex file into an object, find all instances of a '\newcommand' into a generator object that I can iterate:
from TexSoup import TexSoup
soup = TexSoup(open('slatex.tex'))
newcommands = list(soup.find_all('newcommand'))
I know that this is pulling each '\newcommand' into its own element and maintaining the formats properly because I can easily print them out one at a time.
I'm stuck trying to figure out how to pull the '\newcommand' from each item, get the name of the item into a dictionary key and the value into a dictionary value. I'd like to think that TexSoup exposes those with some kind of attribute or method but I can't find anything about it. If it doesn't, am I back to looking at regular expressions again?
Each of the \newcommands has two required arguments, denoted using {}. As a result, we can
access each newcommand's arguments, and
access the value of each argument
With your definition of slatex.tex above, we can obtain
{'\\finDate': 'December 31, 2018', '\\startDate': 'January 1, 2018'}
using the following script
from pprint import pprint
from TexSoup import TexSoup
soup = TexSoup(open('slatex.tex'))
newcommands = list(soup.find_all('newcommand'))
result = {}
for newcommand in newcommands:
key, value = newcommand.args
result[key.value] = value.value
pprint(result)
*On a side note, TexSoup doesn't yet understand that these redefined variables will have tangible impact on the rest of the document. It treats them as any other command, passively.

Python LXML create xml with specific namespace and structure

I am trying to create an XML export from a python application and need to structure the file in a specific way for the external recipient of the file.
The root node needs to be namespaced, but the child nodes should not.
The root node of should look like this:
<ns0:SalesInvoice_Custom_Xml xmlns:ns0="http://EDI-export/Invoice">...</ns0:SalesInvoice_Custom_Xml>
I have tried to generate the same node using the lxml library on Python 2.7, but it does not behave as expected.
Here is the code that should generate the root node:
def create_edi(self, document):
_logger.info("INFO: Started creating EDI invoice with invoice number %s", document.number)
rootNs = etree.QName("ns0", "SalesInvoice_Custom_Xml")
doc = etree.Element(rootNs, nsmap={
'ns0': "http://EDI-export/Invoice"
})
This gives the following output
<ns1:SalesInvoice_Custom_Xml xmlns:ns0="http://EDI-export/Invoice" xmlns:ns1="ns0">...</ns1:SalesInvoice_Custom_Xml>
What should I change in my code to get lxml to generate the correct root node
You need to use
rootNs = etree.QName(ns0, "SalesInvoice_Custom_Xml")
with
ns0 = "http://EDI-export/Invoice"
The whole data structure itself is agnostic of any namespace mapping you might apply later, i. e. the tags know the true namespaces (e. g. http://EDI-export/Invoice) not their mapping (e. g. ns0).
Later, when you finally serialize this into a string, a namespace mapping is needed. Then (and only then) a namespace mapping will be used.
Also, after parsing you can ask the etree object what namespace mapping had been found during parsing. But that is not part of the structure, it is just additional information about how the structure had been encoded as string. Consider that the following two XMLs are logically equal:
<x:tag xmlns:x="namespace"></x:tag>
and
<y:tag xmlns:y="namespace"></y:tag>
After parsing, their structures will be equal, their namespace mappings will not.

How to access PyNode from a PyNode list?

I ran this example code with 2 polyCubes in scene.
import pymel.core as pymel
pymel.select('pCube1', 'blinn1')
print pymel.ls(sl = True)
print pymel.ls(sl = True)[0]
and this is my output
[nt.Transform(u'pCube1'), nt.Blinn(u'blinn1')]
pCube1
I know the elements inside this list are PyNodes, but printing them gives out a string type name of the node. Is there anyway to access the PyNode directly from this list?
Found the answer myself.
So apparently the Script Editor returns a representation of PyNode when we print it. Like it's an overloaded str. It is still a PyNode but looks like a string only in Maya's Script Editor. To make it actually appear like a PyNode, we have to use repr() or enclose in back-ticks (`)
Here is the link where I found the answer.
: http://download.autodesk.com/us/maya/2011help/pymel/tutorial.html
Formatting: Read Me First to Avoid Confusion section

Process string using sphinx

I was wondering whether it is possible to process a string in python, using sphinx. Basically, I would like to pass a string containing restructured text to sphinx, and then generate the corresponding HTML output. I meant something like this
import sphinx.something
s = 'some restructured text'
html_out = sphinx.something(s)
However, I could not find anything along these lines. So, is this possible, and if so, how would one do this?
The quickest solution I've seen is:
from docutils.examples import html_body
def rst(rstStr):
return html_body(rstStr, input_encoding='utf-8',
output_encoding='utf-8').strip()
I'd be interested myself in better solutions..

Categories