Skip to content

Instantly share code, notes, and snippets.

@steveroush
Created May 31, 2024 19:32
Show Gist options
  • Save steveroush/581d3f690d5422f830a317ad35d1f030 to your computer and use it in GitHub Desktop.
Save steveroush/581d3f690d5422f830a317ad35d1f030 to your computer and use it in GitHub Desktop.
Graphviz - a program to swap head & tail of edges
/****************************************************************
swapHeadTail.gvpr - swap tail & head of edge(s)
(only seems to have "real" effect when using dot)
replaces edges with tail & head swapped
and (unless using -a0 option) "fixes" all the attribures that are associated with head or tail
to swap ALL edges, either add
- edge [swap=1] to your myFile.gv, then
gvpr -cf swapTailHead.gvpr myFile.gv | dot -T...
or
- gvpr -a1 -cf swapTailHead.gvpr myFile.gv | dot -T...
*****************************************************************/
BEG_G {
string att, val, tailHeadAtt[], swapAtt[];
string swappedAtt, swappedVal, tmpS, swapStyle, thisSwapStyle[], help;
int a, i, Delete[];
edge_t anEdge, newEdge;
help='
swapHeadTail.gvpr - swap tail & head of edge(s)
(only seems to have "real" effect when using dot)
replaces edges with tail & head swapped
and (unless using -a0 option) "fixes" all the attribures that are associated with head or tail
to swap ALL edges, either add
- edge [swap=1] to your myFile.gv, then
gvpr -cf swapTailHead.gvpr myFile.gv | dot -T...
or
- gvpr -a1 -cf swapTailHead.gvpr myFile.gv | dot -T...
';
swapStyle="";
i=0;
while (i<ARGC) {
if (ARGV[i]=="0|1") {
swapStyle=ARGV[i];
} else {
printf(2,help);
exit(0);
}
i++;
}
print("// FILENAME: ",$F);
a=0;
unset(tailHeadAtt);
for (att = fstAttr($G,"E"); att != ""; att = nxtAttr($G,"E",att)) {
//print("// att: ", att);
if (att=="*@(head|tail)*" || att=="dir") {
tailHeadAtt[++a]=att;
//print("// ATT: ", att);
}
}
}
E{
if (swapStyle!="" || (hasAttr($, "swap") && $.swap!="")) {
Delete[$]=1;
if (swapStyle!="")
thisSwapStyle[$]=swapStyle;
else // if (hasAttr($, "swap") && $.swap!="")
thisSwapStyle[$]=$.swap;
}
}
END_G{
for (Delete[anEdge]) {
// do we swap attributes also?
if (thisSwapStyle[anEdge]!="0") {
unset(swapAtt);
for (tailHeadAtt[i]) {
att=tailHeadAtt[i];
if (hasAttr(anEdge, att)) {
val=aget(anEdge, att);
tmpS="_Original_"+(string)att;
aset(anEdge, tmpS, val); // for debugging, keep original
//print("// ATT & VAL: >", att, "< >", val, "<");
if (att=="dir" && val=="")
val="forward";
if (val!="" ) {
swappedVal=val;
if (att=="*head*")
swappedAtt=sub(att,"head","tail");
else if (att=="*tail*")
swappedAtt=sub(att,"tail","head");
else { // att==dir
swappedAtt=att;
if (val=="forward")
swappedVal="back";
else if (val=="back")
swappedVal="forward";
}
}
print("// swap ", anEdge.name, " ", att, " ", val);
swapAtt[swappedAtt]=swappedVal;
aset(anEdge, att, ""); // as close to erase/delete as possible
}
}
}
//print("// old: ", anEdge.name," ",anEdge.tail.name, " :: ", anEdge.head.name);
newEdge=edge(anEdge.head, anEdge.tail, "");
//print("// new: ", newEdge.name);
copyA(anEdge, newEdge); // copy all the rest of the attributes
for (swapAtt[att]) {
aset(newEdge, att, swapAtt[att]);
}
delete($G, anEdge);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment