Number: 1874
Title: [New Feature Request] Add a CSS-like "class" attribute
Submitter: Oren Ben-Kiki
Date: Sat Feb 6 20:04:22 2010
Subsys: Other
Version:
System: *-*-
Severity: minor
Problem: Address the need for specifying styles once, and reuse them in many nodes/edges.
Input:
digraph new_feature_request {
  node [ shape = circle, color = black ];
  node.foo [ shape = rectangle, color = red ];
  node.bar [ shape = diamond, color = green ];
  node.foo.bar [ shape = ellipse ];
  C [ label = "black circle" ];
  R [ label = "red rectangle", class = foo ];
  D [ label = "green diamond", class = "bar" ];
  E [ label = "green ellipse", class = "foo bar" ];
  edge [ style = solid, arrowsize = 1 ];
  edge.foo [ style = dashed ];
  edge.bar [ style = dotted ];
  edge.baz [ arrowsize = 2 ];
  C -> R [ label = "solid big black arrow", class = baz ];
  R -> D [ label = "dotted big black arrow", class = "baz foo" ];
  D -> E [ label = "bold big black arrow", class = "foo baz", style = bold ];
  graph.foo [ /* etc. */ ];
}
Comments:
Pros of this approach:

- It makes it *much* easier to manage graphs with several consistent styles or combinations of styles.
- It is a simple solution (both technically and conceptually).
- It is immediately intuitive to everyone who used CSS.
- It is backward compatible with existing files.
- It is a natural extension of the current syntax.

[north] This is very interesting and we have often thought about a feature like this.

The implementation would probably be a little more complicated than just changing the parser. What if "classes" are modified after the graph has been read? (Or can classes be set on objects in a graph that is constructed entirely in memory?) The graph output routine probably should be aware of classes at least to avoid writing out all the individual attributes that are class-defined.
Fix:
In Parser.y, add the rule:


    class_list : T_class symbol class_list { ...remember class... } | /* empty */ ;
(Whete T_class is '.'). Also, change the attr_stmt rule to:
    attr_stmt : attr_class class_list attr_list | attr_set ;
Finally, in the C code:

- Use the fact "proto" is already a linked list.
- Add a member to each list entry specifying a set of classes.
- This will mean "proto" will have multiple entries per stack level.
- Map class name to index similarly to how attribute names are handled.
- Map the class attribute to a set of classes.
- Only apply a "proto" entry if its set of classes is contained in the affected node's/edge's set of classes.
If I create a patch along the above line, would it be accepted?
Owner: *
Status: Request