work towards solution for round tripping GV→GXL→GV
This series starts addressing #517 (closed). It solves the GV→GXL part, but not the remaining GXL→GV part.
@truenorth et al, can I get some guidance on this? I have the below sort-of obviously-wrong outstanding changes in my working directory. They lead to the interesting but useless outcome on the #517 (closed) example of a label of "<<TABLE><TR><TD>(</TD><TD>A</TD><TD>)</TD></TR></TABLE>>"
. I.e. the gxl2gv
code correctly recognizes an HTML string, but the result is still "
wrapped.
The (my) core problem here is that gxl2gv
is constructing the Dot graph programmatically rather than as text. This is a good thing. But it calls agxset
to add attributes. AFAICT this function assumes the attribute it is adding is a non-HTML string. There appears to be no equivalent to add an HTML string. Unpacking that a little… agxset
unconditionally calls agstrdup
, while in this case I want to call agstrdup_html
.
Does this make sense and is my summary correct? If so, can you suggest a way around this?
diff --git cmd/tools/gxl2gv.c cmd/tools/gxl2gv.c
index f65e63fe7..573daaa8e 100644
--- cmd/tools/gxl2gv.c
+++ cmd/tools/gxl2gv.c
@@ -11,6 +11,7 @@
#include "convert.h"
#include <cgraph/agxbuf.h>
+#include <cgraph/sprint.h>
#ifdef HAVE_EXPAT
#include <expat.h>
#include <ctype.h>
@@ -38,6 +39,7 @@
#define TAG_GRAPH 0
#define TAG_NODE 1
#define TAG_EDGE 2
+#define TAG_HTML_STRING 3
typedef struct slist slist;
struct slist {
@@ -535,6 +537,8 @@ startElementHandler(void *userData, const char *name, const char **atts)
ud->globalAttrType = TAG_EDGE;
else if (strcmp("graph", atts[pos]) == 0)
ud->globalAttrType = TAG_GRAPH;
+ else if (strcmp("HTML string", atts[pos]) == 0)
+ ud->globalAttrType = TAG_HTML_STRING;
} else {
ud->globalAttrType = TAG_NONE;
}
@@ -636,6 +640,12 @@ static void endElementHandler(void *userData, const char *name)
case TAG_GRAPH:
setGraphAttr(G, name, value, ud);
break;
+ case TAG_HTML_STRING: {
+ char *angle_wrapped = gv_sprint_or_exit("<%s>", value);
+ setAttr(name, angle_wrapped, ud);
+ free(angle_wrapped);
+ break;
+ }
}
free(dynbuf);
ud->globalAttrType = TAG_NONE;