How to make node renaming by gvpr?

Hello!
I am trying to rename node of graph by command in console:

 gvpr -c 'N[name == "Q23"]{ name = "ZQ"}' py_chat.dot > prep_py_chat.dot

Answer of gvpr:

gvpr: 
 -- name: cannot set value

How to fix this issue or may be there are another method to rename nodes in graph?

Best regards,
Igor

I’m sorry, I don’t think this is possible in gvpr, other than brute force creating a new node and copying the attributes of the old node. There is a copyA function in gvpr to help that. The wrinkle is that, if iterating over nodes, a new node can appear later in the iteration, so you need more bookkeeping to skip them. (For better or worse, the preferred style in gvpr is generally to create new output graphs, not edit input graphs.)

That being said, it’s interesting that the underlying graph representation library has an internal API to rename graph objects (declared here, implemented here) but it’s not callable externally. Clearly this is intentional, though I’m not sure why. git blame reports Erwin Janssen (from GitHub days) and John Ellson @ellson respectively. I don’t remember them being involved with this layer of the graph library but maybe they were, especially John. The question is what hazards exist in allowing clients to call agrename().

So, it turns out there is an external API agrelabel_node(), and it’s not hard to write a modification to enable this in gvpr.

north@margil lib % cat rename
N[$.name=="oldname"] {rename($,"newname");}
north@margil lib % gvpr -c -f rename
digraph G { x; oldname }
digraph G {
	x;
	newname;
}
north@margil lib %

If we decided to enable this, good news is that it hopefully wouldn’t change anything about node scanning because this is done in the internally managed order of object creation, that doesn’t change if the object is renamed.

The slightly less good news is one might ask why this isn’t handled by just reassigning $.name, but at least an understandable error is emitted. But why not call agrelabel_node or why not expose agrename(obj, name) and allow any object to be renamed.

Thank you for detailed answer!
Also, brute force method should include copying the edges connected to the node.

I think the ability to rename nodes is very important because it provides a way to avoid node name conflicts when using the #include directive to merge graphs.

I’m creating a merge request for this.

1 Like

Thanks a lot!

Submitted, Define gvpr "rename" builtin to call agrelabel_node() and update documentation. (!4122) · Merge requests · graphviz / graphviz · GitLab

The pipeline failed, but only because one build (windows-mingw64) ran more than 1h and timed out.

1 Like

Note that there may be a problem if you want to keep the original label.
e.g. label=“…\N…”, label=“…\E…”, label=“…\T…” will all now take on the new node name, not the original name.

Good catch. I wonder if there’s a function to apply those bindings, or if that’s even a good idea.