Can you change the case of the states in your graph?

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.

1 Like

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.

1 Like

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).

  1. 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;
}
  1. run this command on your input file. It will simplify identifying default node labels dot -Tcanon myfile.gv >myfile.can
  2. run this command to capitalize your node labels: gvpr -c -f uppercase.gvpr myfile.can >myfile.upper
  3. (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.