53#define ND_gid(n) (((gvid_t*)aggetrec(n, ID, 0))->id)
54#define ED_gid(n) (((gvid_t*)aggetrec(n, ID, 0))->id)
55#define GD_gid(n) (((gvid_t*)aggetrec(n, ID, 0))->id)
88 for (
s = input; (c = *
s);
s++) {
128 for (i = level; i > 0; i--)
153 const size_t cnt = polyline->
cnt;
157 for (
size_t i = 0; i <
cnt; i++) {
159 gvprintf(job,
"[%.03f,%.03f]", pts[i].x, pts[i].y);
169 for (i = 0; i < n_stops; i++) {
171 gvprintf(job,
"{\"frac\": %.03f, \"color\": ", stp[i].frac);
181 gvprintf(job,
"\"p0\": [%.03f,%.03f,%.03f],\n", rg->
x0, rg->
y0, rg->
r0);
183 gvprintf(job,
"\"p1\": [%.03f,%.03f,%.03f],\n", rg->
x1, rg->
y1, rg->
r1);
191 gvprintf(job,
"\"p0\": [%.03f,%.03f],\n", lg->
x0, lg->
y0);
193 gvprintf(job,
"\"p1\": [%.03f,%.03f],\n", lg->
x1, lg->
y1);
209 gvprintf(job,
"\"rect\": [%.03f,%.03f,%.03f,%.03f]\n",
234 gvprintf(job,
"\"align\": \"%c\",\n",
240 gvputs(job,
"\"text\": ");
248 gvprintf(job,
"\"grad\": \"none\",\n");
250 gvputs(job,
"\"color\": ");
259 gvprintf(job,
"\"grad\": \"none\",\n");
261 gvputs(job,
"\"color\": ");
267 gvprintf(job,
"\"grad\": \"linear\",\n");
272 gvprintf(job,
"\"grad\": \"radial\",\n");
283 gvputs(job,
"\"face\": ");
290 gvputs(job,
"\"style\": ");
313 if (!val || *val ==
'\0')
return;
317 agwarningf(
"Could not parse xdot \"%s\"\n", val);
324 for (
size_t i = 0; i < cmds->
cnt; i++) {
337 return streq(name,
"_draw_") ||
streq(name,
"_ldraw_") ||
338 streq(name,
"_hdraw_") ||
streq(name,
"_tdraw_") ||
339 streq(name,
"_hldraw_") ||
streq(name,
"_tldraw_");
351 if (!(attrval =
agxget(obj, sym)))
continue;
352 if (*attrval ==
'\0' && !
streq(sym->
name,
"label"))
continue;
369 gvputs(job,
"\"name\": ");
401 if (!sg)
return false;
406 gvputs(job,
"\"objects\": [\n");
408 gvputs(job,
"\"subgraphs\": [\n");
411 const char *separator =
"";
495 gvputs(job,
"\"edges\": [\n");
498 for (
size_t j = 0; j < count; ++j) {
524 gvputs(job,
"\"name\": ");
540 bool only_clusters =
true;
543 only_clusters =
false;
549 if (has_subgs &&
top) {
561 gvputs(job,
"\"objects\": [\n");
566 gvputs(job,
"\"nodes\": [\n");
569 const char *separator =
"";
574 separator =
top ?
",\n" :
",";
598 offsetof(
intm, link),
607 if (ip)
return ip->
v;
617 agwarningf(
"Duplicate cluster name \"%s\"\n", name);
661 ND_gid(np) = sgcnt + ncnt++;
677 gvprintf(job,
"\"_subgraph_cnt\": %d", sgcnt);
Memory allocation wrappers that exit on failure.
static char * gv_strdup(const char *original)
static void * gv_calloc(size_t nmemb, size_t size)
static void * gv_alloc(size_t size)
CDT_API int dtclose(Dt_t *)
CDT_API Dtmethod_t * Dtoset
ordered set (self-adjusting tree)
CDT_API Dt_t * dtopen(Dtdisc_t *, Dtmethod_t *)
char * latin1ToUTF8(char *s)
Converts string from Latin1 encoding to utf8. Also translates HTML entities.
bool is_a_cluster(Agraph_t *g)
static void ins(Dict_t *d, Dtlink_t **set, Agedge_t *e)
static int cnt(Dict_t *d, Dtlink_t **set)
Agsym_t * agnxtattr(Agraph_t *g, int kind, Agsym_t *attr)
permits traversing the list of attributes of a given type
char * agxget(void *obj, Agsym_t *sym)
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
void agwarningf(const char *fmt,...)
int agisdirected(Agraph_t *g)
int agisstrict(Agraph_t *g)
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Agnode_t * agfstnode(Agraph_t *g)
char * agnameof(void *)
returns a string descriptor for the object.
#define AGTYPE(obj)
returns AGRAPH, AGNODE, or AGEDGE depending on the type of the object
Agraph_t * agroot(void *obj)
void aginit(Agraph_t *g, int kind, const char *rec_name, int rec_size, int move_to_front)
attach new records to objects of specified kind
Agraph_t * agfstsubg(Agraph_t *g)
Agraph_t * agnxtsubg(Agraph_t *subg)
int gvRender(GVC_t *gvc, graph_t *g, const char *format, FILE *out)
void attach_attrs(graph_t *g)
Graphviz context library.
GVCINT_API void gvFreeCloneGVC(GVC_t *)
GVCINT_API GVC_t * gvCloneGVC(GVC_t *)
#define GVRENDER_DOES_TOOLTIPS
#define LAYOUT_NOT_REQUIRED
#define GVRENDER_DOES_MAPS
#define GVRENDER_DOES_TARGETS
#define GVRENDER_DOES_TRANSFORM
static void color(Agraph_t *g)
int gvputc(GVJ_t *job, int c)
int gvputs(GVJ_t *job, const char *s)
void gvprintf(GVJ_t *job, const char *format,...)
static void indent(GVJ_t *job, int level)
int(* putstrfn)(void *chan, const char *str)
static int lookup(Dt_t *map, char *name)
static void write_radial_grad(GVJ_t *job, xdot_radial_grad *rg, state_t *sp)
static void write_xdot(xdot_op *op, GVJ_t *job, state_t *sp)
static void write_linear_grad(GVJ_t *job, xdot_linear_grad *lg, state_t *sp)
static void write_subg(Agraph_t *g, GVJ_t *job, state_t *sp)
static void write_attrs(Agobj_t *obj, GVJ_t *job, state_t *sp)
static gvrender_engine_t json_engine
static int write_edges(Agraph_t *g, GVJ_t *job, bool top, state_t *sp)
static void write_edge(Agedge_t *e, GVJ_t *job, bool top, state_t *sp)
static bool write_subgs(Agraph_t *g, GVJ_t *job, bool top, state_t *sp)
static int write_nodes(Agraph_t *g, GVJ_t *job, bool top, bool has_subgs, state_t *sp)
static gvdevice_features_t device_features_json_nop
static void set_attrwf(Agraph_t *g, bool toplevel, bool value)
static void write_polyline(GVJ_t *job, xdot_polyline *polyline)
gvplugin_installed_t gvdevice_json_types[]
static int label_subgs(Agraph_t *g, int lbl, Dt_t *map)
static void write_graph(Agraph_t *g, GVJ_t *job, bool top, state_t *sp)
static void write_hdr(Agraph_t *g, GVJ_t *job, bool top, state_t *sp)
static void freef(void *ident)
int(* flushfn)(void *chan)
static void stoj(char *ins, state_t *sp, GVJ_t *job)
gvplugin_installed_t gvrender_json_types[]
static gvdevice_features_t device_features_json
static gvrender_features_t render_features_json
static void write_xdots(char *val, GVJ_t *job, state_t *sp)
static int agseqasc(const void *x, const void *y)
static void write_node(Agnode_t *n, GVJ_t *job, bool top, state_t *sp)
static void json_end_graph(GVJ_t *job)
static void insert(Dt_t *map, char *name, int v)
static void write_stops(GVJ_t *job, int n_stops, xdot_color_stop *stp, state_t *sp)
static bool isXDot(const char *name)
static void json_begin_graph(GVJ_t *job)
textitem scanner parser str
static Agedge_t * top(edge_stack_t *sp)
static bool streq(const char *a, const char *b)
are a and b equal?
int(* afread)(void *chan, char *buf, int bufsize)
int(* putstr)(void *chan, const char *str)
a generic header of Agraph_s, Agnode_s and Agedge_s
Agclos_t * clos
shared resources
implementation of Agrec_t
gvplugin_active_render_t render
information the ID allocator needs to do its job
xdot * parseXDot(char *s)
parsing and deparsing of xdot operations