How do you convert all the states of your graph to an upper or lower case?
[“State” is not a Graphviz term, I’m guessing that you are using nodes (and node labels) to represent states.]
Are you wanting to capitalize
- the first letter of the first word in each node label
- the first letter of every word in each node label
- every character of every word of each node label
- or something else?
[sorry, but many years of receiving requirements has taught me to nail things down]
Whatever your answer, I think we can solve your problem.
The third one - every character of every word of each more label.
Can you post a copy of your file?
It is pretty easy to capitalize “simple” text, but things quickly get quite messy if record nodes, html-like nodes, or non-ascii character sets are involved.
It is simple text, no special characters. I simply want the format on how to do that because the simple attribute method doesn’t seem to be working.
[Every now and then I think some task will be trivial and it is actually quite a challenge, at least for me]
There is nothing in the Graphviz language to change case (capitalization). Html-like nodes do allow some formatting changes, but that is it.
I thought the GVPR language (https://www.graphviz.org/pdf/gvpr.1.pdf) would make this task trivial, but not so much. Doable, but not trivial. (Whine).
Anyway, here is a modestly-tested program that capitalizes (or de-capilalizes!) all the ASCII characters in node labels only (not xlabels, edge labels, graph/cluster labels).
- copy this to a file named uppercase.gvpr
BEGIN{
string U, D, capStr;
int lbl[], upper=99;
graph_t Root, parentG[];
/////////////////////////////////////////////////////////////////////////////
graph_t graphTraverse (graph_t thisG) {
graph_t aGraph;
node_t aNode;
if (isAttr(thisG, "N", "label")){
D=getDflt(thisG, "N", "label");
//print("// default: ",thisG.name," >",D,"<");
} //else print("// no default");
for (aGraph = fstsubg(thisG); aGraph; aGraph = nxtsubg(aGraph)) {
//print ("// graph: >", aGraph.name,"<");
// find all nodes that have this graph as immediate parent
for (aNode=fstnode(aGraph);aNode;aNode = nxtnode_sg(aGraph, aNode)){
if (parentG[aNode]==NULL || isIn(parentG[aNode], aGraph))
parentG[aNode]=aGraph;
//print("// parent : ", parentG[aNode].name, " node: ", aNode.name);
}
aGraph = graphTraverse(aGraph);
}
return thisG;
} // end of graphTraverse
/////////////////////////////////////////////////////////////////////////////
int allCaps(obj_t thisO, string oType, string lblType){
int rc, i;
string val, part1, part2, part3;;
//print("// ", thisO.name, " ", lblType);
// default values are already applied (if appropriate)
if (hasAttr(thisO, lblType)){
val=aget(thisO, lblType);
i=match(val,"\\\\N"); // lots of backslashes needed, ugh
//print("// has att: >",val, "< ", lblType, " ",i);
if (i>-1){
part1=part2=part3="";
if (i>0) part1=substr(val,0,i);
if (i+2<length(val)) part2=substr(val,2);
part3=thisO.name;
if (upper==1)
capStr=toupper(part1+part2+part3);
else
capStr=tolower(part1+part2+part3);
}else{
if (upper==1)
capStr=toupper(val);
else
capStr=tolower(val);
}
rc=1;
//print("// result: ",capStr, " :",rc);
}else{ // default?
if (oType=="N"){
if (isAttr(parentG[thisO], oType, lblType))
D=getDflt(parentG[thisO], oType, lblType);
else
D="";
//print("// default: ",D);
}else{ // not node, punt
D="";
}
if (D==""){
rc=0;
}else{
//print("// use default: ",D);
if (upper==1)
capStr=gsub(D,"\N",toupper(thisO.name));
else
capStr=gsub(D,"\N",tolower(thisO.name));
rc=1;
}
}
//print ("// RETURNING >", capStr,"< ",rc);
return rc;
} // end of allCaps
// lbl array not currently used, future
lbl["label"]=1;
lbl["headlabel"]=1;
lbl["taillabel"]=1;
lbl["xlabel"]=1;
}
BEG_G{
Root=$G;
graphTraverse ($G);
if (ARGC == 0) upper=1;
if (ARGC >1) {printf (2, "Only one argument allowed\n");exit(9);}
if (ARGC ==1 && ARGV[0]=="[Uu]") upper=1;
if (ARGC ==1 && ARGV[0]=="[Ll]") upper=0;
if (upper>1){printf (2, "Illegal argument (%s). Use L or U.\n",ARGV[0]);exit(9);}
}
N{
if (allCaps($, "N", "label"))
$.label=capStr;
}
- run this command on your input file. It will simplify identifying default node labels
dot -Tcanon myfile.gv >myfile.can
- run this command to capitalize your node labels:
gvpr -c -f uppercase.gvpr myfile.can >myfile.upper
- (finally) run dot (or any Graphviz program) like so:
dot -Tsvg myfile.upper >myfile.svg
If you want all lowercase, use this for the gvpr command line gvpr -al -c -f uppercase.gvpr myfile.can >myfile.upper
All-in-all a ridiculous (but real) solution.