58 #define ND_gid(n) (((gvid_t*)aggetrec(n, ID, FALSE))->id)
59 #define ED_gid(n) (((gvid_t*)aggetrec(n, ID, FALSE))->id)
60 #define GD_gid(n) (((gvid_t*)aggetrec(n, ID, FALSE))->id)
62 #define IS_CLUSTER(s) (!strncmp(agnameof(s), "cluster", 7))
64 static void json_begin_graph(
GVJ_t *job)
77 #define LOCALNAMEPREFIX '%'
82 static char* stoj (
char* ins,
state_t* sp)
96 for (s = input; (c = *s); s++) {
134 static void indent(
GVJ_t * job,
int level)
137 for (i = level; i > 0; i--)
141 static void set_attrwf(
Agraph_t * g,
int toplevel,
int value)
149 set_attrwf(subg,
FALSE, value);
163 int cnt = polyline->
cnt;
167 for (i = 0; i < cnt; i++) {
169 gvprintf(job,
"[%.03f,%.03f]", pts[i].x, pts[i].y);
179 for (i = 0; i < n_stops; i++) {
181 gvprintf(job,
"{\"frac\": %.03f, \"color\": \"%s\"}",
182 stp[i].frac, stoj(stp[i].color, sp));
189 indent(job, sp->
Level);
190 gvprintf(job,
"\"p0\": [%.03f,%.03f,%.03f],\n", rg->
x0, rg->
y0, rg->
r0);
191 indent(job, sp->
Level);
192 gvprintf(job,
"\"p1\": [%.03f,%.03f,%.03f],\n", rg->
x1, rg->
y1, rg->
r1);
193 indent(job, sp->
Level);
199 indent(job, sp->
Level);
200 gvprintf(job,
"\"p0\": [%.03f,%.03f],\n", lg->
x0, lg->
y0);
201 indent(job, sp->
Level);
202 gvprintf(job,
"\"p1\": [%.03f,%.03f],\n", lg->
x1, lg->
y1);
203 indent(job, sp->
Level);
209 indent(job, sp->
Level++);
211 indent(job, sp->
Level);
218 indent(job, sp->
Level);
219 gvprintf(job,
"\"rect\": [%.03f,%.03f,%.03f,%.03f]\n",
226 indent(job, sp->
Level);
227 write_polyline (job, &op->
u.
polygon);
233 indent(job, sp->
Level);
234 write_polyline (job, &op->
u.
bezier);
238 indent(job, sp->
Level);
243 indent(job, sp->
Level);
245 indent(job, sp->
Level);
246 gvprintf(job,
"\"align\": \"%c\",\n",
249 indent(job, sp->
Level);
251 indent(job, sp->
Level);
258 indent(job, sp->
Level);
259 gvprintf(job,
"\"grad\": \"none\",\n");
260 indent(job, sp->
Level);
267 indent(job, sp->
Level);
269 gvprintf(job,
"\"grad\": \"none\",\n");
270 indent(job, sp->
Level);
271 gvprintf(job,
"\"color\": \"%s\"\n",
276 gvprintf(job,
"\"grad\": \"linear\",\n");
277 indent(job, sp->
Level);
281 gvprintf(job,
"\"grad\": \"radial\",\n");
282 indent(job, sp->
Level);
289 indent(job, sp->
Level);
291 indent(job, sp->
Level);
296 indent(job, sp->
Level);
303 indent(job, sp->
Level);
308 indent(job, sp->
Level);
312 static void write_xdots (
char * val,
GVJ_t * job,
state_t* sp)
318 if (!val || (*val ==
'\0'))
return;
322 agerr(
AGWARN,
"Could not parse xdot \"%s\"\n", val);
327 indent(job, sp->
Level++);
329 for (i = 0; i < cmds->
cnt; i++) {
334 write_xdot (cmds->
ops+i, job, sp);
338 indent(job, sp->
Level);
343 static int isXDot (
char* name)
345 return ((*name++ ==
'_') &&
346 (
streq(name,
"draw_") ||
streq(name,
"ldraw_") ||
347 streq(name,
"hdraw_") ||
streq(name,
"tdraw_") ||
348 streq(name,
"hldraw_") ||
streq(name,
"tldraw_")));
359 for (; sym; sym =
agnxtattr(g, type, sym)) {
360 if (!(attrval =
agxget(obj, sym)))
continue;
361 if ((*attrval ==
'\0') && !
streq(sym->
name,
"label"))
continue;
363 indent(job, sp->
Level);
366 write_xdots(
agxget(obj, sym), job, sp);
377 indent(job, sp->
Level);
378 gvprintf(job,
"\"name\": \"%s\"", stoj (name, sp));
382 indent(job, sp->
Level);
384 indent(job, sp->
Level);
395 write_graph (g, job,
FALSE, sp);
398 write_subg(sg, job, sp);
438 indent(job, sp->
Level++);
440 gvputs(job,
"\"objects\": [\n");
442 gvputs(job,
"\"subgraphs\": [\n");
443 indent(job, sp->
Level);
451 write_subg (sg, job, sp);
458 indent(job, sp->
Level);
468 indent(job, sp->
Level++);
470 indent(job, sp->
Level);
472 indent(job, sp->
Level);
474 indent(job, sp->
Level);
476 write_attrs((
Agobj_t*)e, job, sp);
479 indent(job, sp->
Level);
506 indent(job, sp->
Level++);
507 gvputs(job,
"\"edges\": [\n");
509 indent(job, sp->
Level);
519 write_edge(ep, job, top, sp);
524 indent(job, sp->
Level);
532 indent(job, sp->
Level++);
534 indent(job, sp->
Level);
536 indent(job, sp->
Level);
538 write_attrs((
Agobj_t*)n, job, sp);
541 indent(job, sp->
Level);
556 if (has_subgs && top) {
559 indent(job, sp->
Level);
567 indent(job, sp->
Level++);
568 gvputs(job,
"\"objects\": [\n");
572 indent(job, sp->
Level++);
573 gvputs(job,
"\"nodes\": [\n");
574 indent(job, sp->
Level);
585 write_node (n, job, top, sp);
589 indent(job, sp->
Level);
609 offsetof(
intm, link),
618 #define NEW(t) (t*)calloc(1,sizeof(t))
620 static int lookup (
Dt_t* map,
char* name)
623 if (ip)
return ip->
v;
627 static void insert (
Dt_t* map,
char* name,
int v)
633 agerr(
AGWARN,
"Duplicate cluster name \"%s\"\n", name);
637 ip->
id = strdup(name);
652 lbl = label_subgs(sg, lbl, map);
673 sgcnt = label_subgs(g, sgcnt, map);
679 ND_gid(np) = sgcnt + ncnt++;
688 indent(job, sp->
Level++);
690 write_hdr(g, job, top, sp);
691 write_attrs((
Agobj_t*)g, job, sp);
694 indent(job, sp->
Level);
695 gvprintf(job,
"\"_subgraph_cnt\": %d", sgcnt);
698 indent(job, sp->
Level);
701 has_subgs = write_subgs(g, job, top, sp);
702 write_nodes (g, job, top, has_subgs, sp);
703 write_edges (g, job, top, sp);
706 indent(job, sp->
Level);
716 static void json_end_graph(
GVJ_t *job)
737 write_graph(g, job,
TRUE, &sp);
int(* Dtcompar_f)(Dt_t *, void *, void *, Dtdisc_t *)
CDT_API int dtclose(Dt_t *)
void *(* Dtmake_f)(Dt_t *, void *, Dtdisc_t *)
char * latin1ToUTF8(char *s)
#define LAYOUT_NOT_REQUIRED
CGRAPH_API Agiodisc_t AgIoDisc
Agsym_t * agnxtattr(Agraph_t *g, int kind, Agsym_t *attr)
CDT_API Dtmethod_t * Dtoset
CGRAPH_API int agisdirected(Agraph_t *g)
size_t agxbput(agxbuf *xb, const char *s)
void gvFreeCloneGVC(GVC_t *)
gvrender_engine_t json_engine
int agerr(agerrlevel_t level, const char *fmt,...)
xdot * parseXDot(char *s)
CGRAPH_API Agraph_t * agfstsubg(Agraph_t *g)
CGRAPH_API Agraph_t * agroot(void *obj)
CGRAPH_API Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
GVC_t * gvCloneGVC(GVC_t *)
gvplugin_installed_t gvdevice_json_types[]
#define GVRENDER_DOES_TRANSFORM
int(* flushfn)(void *chan)
CDT_API Dt_t * dtopen(Dtdisc_t *, Dtmethod_t *)
CGRAPH_API Agraph_t * agnxtsubg(Agraph_t *subg)
CGRAPH_API Agnode_t * agtail(Agedge_t *e)
int gvputs(GVJ_t *job, const char *s)
gvplugin_installed_t gvrender_json_types[]
#define GVRENDER_DOES_TARGETS
CGRAPH_API Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
#define GVRENDER_DOES_TOOLTIPS
CGRAPH_API int agisstrict(Agraph_t *g)
gvplugin_active_render_t render
CGRAPH_API Agnode_t * aghead(Agedge_t *e)
gvrender_features_t render_features_json1
CGRAPH_API char * agnameof(void *)
int(* afread)(void *chan, char *buf, int bufsize)
gvdevice_features_t device_features_json
void agxbinit(agxbuf *xb, unsigned int hint, unsigned char *init)
CGRAPH_API Agnode_t * agfstnode(Agraph_t *g)
CGRAPH_API void aginit(Agraph_t *g, int kind, char *rec_name, int rec_size, int move_to_front)
int(* putstrfn)(void *chan, const char *str)
#define GVRENDER_DOES_MAPS
int gvRender(GVC_t *gvc, graph_t *g, const char *format, FILE *out)
gvrender_features_t render_features_json
void(* Dtfree_f)(Dt_t *, void *, Dtdisc_t *)
int(* putstr)(void *chan, const char *str)
char * agxget(void *obj, Agsym_t *sym)
boolean Attrs_not_written_flag
CGRAPH_API Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
void attach_attrs(graph_t *g)
gvdevice_features_t device_features_json_nop
void gvprintf(GVJ_t *job, const char *format,...)