diff --git a/bank.svg b/bank.svg
new file mode 100644
index 0000000..8a17733
--- /dev/null
+++ b/bank.svg
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/examples/bank_architecture/bank.vis b/examples/bank_architecture/bank.vis
index fb33805..77f3050 100644
--- a/examples/bank_architecture/bank.vis
+++ b/examples/bank_architecture/bank.vis
@@ -28,6 +28,9 @@ structure {
}
styles {
+ structure(group){
+ orientation: vertical
+ }
lanes(group) {
type: textnode
orientation: horizontal
diff --git a/output_multiple_nodes.svg b/output_multiple_nodes.svg
index 8ad8a2e..246734f 100644
--- a/output_multiple_nodes.svg
+++ b/output_multiple_nodes.svg
@@ -1,4 +1,4 @@
-
\ No newline at end of file
+Node 1longer />Node 2 />Node 3is longerthan you are to me />
\ No newline at end of file
diff --git a/src/.DS_Store b/src/.DS_Store
new file mode 100644
index 0000000..0b0ace9
Binary files /dev/null and b/src/.DS_Store differ
diff --git a/src/lib.rs b/src/lib.rs
index 3dd8805..816299d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,61 +1,125 @@
pub mod parse;
pub mod render;
-use crate::Element::{Edge, Node};
-use parse::tokens::TokenType;
+use crate::parse::tokens::TokenType;
use std::collections::HashMap;
use std::fmt::Display;
-#[derive(Debug)]
pub struct Vis {
- pub structure: Vec,
+ pub structure: VisNode,
pub styles: Vec,
}
+impl Vis {
+ pub fn get_node(&self, id: &str) -> Option<&VisNode> {
+ if self.structure.id == id {
+ return Some(&self.structure);
+ } else {
+ for child in &self.structure.children {
+ if child.id == id {
+ return Some(child);
+ }
+ }
+ }
+ None
+ }
+
+ pub fn get_style(&self, node: &VisNode) -> Option<&StyleNode> {
+ let style = self.styles.iter().find(|s| s.id_ref == node.id);
+ if style.is_none() && node.id != "structure" {
+ for child in &node.children {
+ if let Some(style) = self.get_style(child) {
+ return Some(style);
+ }
+ }
+ None
+ } else {
+ None
+ }
+ }
+}
+
+#[derive(Debug, Clone, PartialEq)]
+pub enum NodeType {
+ Node,
+ Edge,
+}
+
#[derive(Debug, Clone)]
-pub enum Element {
- Node(String, Option, Vec),
- Edge(String, String, TokenType, Option),
+pub struct VisNode {
+ pub node_type: NodeType,
+ pub id: String,
+ targetid: Option,
+ pub label: Option,
+ pub children: Vec,
+ pub parent: Option,
+ edgetype: Option,
}
-impl Element {
- pub fn new_node(id: &str, label: Option<&str>, children: Vec) -> Element {
- Element::Node(id.into(), label.map(|s| s.into()), children)
+impl VisNode {
+ pub fn new_node(
+ id: impl Into,
+ label: Option>,
+ children: Vec,
+ ) -> Self {
+ Self {
+ id: id.into(),
+ targetid: None,
+ label: label.map(|s| s.into()),
+ children,
+ parent: None,
+ node_type: NodeType::Node,
+ edgetype: None,
+ }
}
+
pub fn new_edge(
- id: String,
- source: String,
- token: TokenType,
- label: Option,
- ) -> Element {
- Edge(id, source, token, label)
+ sourceid: impl Into,
+ targetid: impl Into,
+ edgetype: TokenType,
+ label: Option>,
+ ) -> Self {
+ Self {
+ id: sourceid.into(),
+ targetid: Some(targetid.into()),
+ edgetype: Some(edgetype),
+ label: label.map(|l| l.into()),
+ children: vec![],
+ parent: None,
+ node_type: NodeType::Edge,
+ }
}
}
-impl Display for Element {
+impl Display for VisNode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- match self {
- Node(id, label, children) => {
+ match &self.node_type {
+ NodeType::Node => {
let mut string = String::new();
string.push_str(&format!(
"Node {{{}: {}",
- id,
- label.as_ref().unwrap_or(&"".to_string())
+ self.id,
+ self.label.as_ref().unwrap_or(&"".to_string())
));
- for child in children {
+ for child in &self.children {
string.push_str(&format!(" {}", child));
}
string.push('}');
write!(f, "{}", string)
}
- Edge(id, source, token, label) => {
- let mut string = "Edge {{".to_string();
- string.push_str(&format!("{} {} {:?}", id, source, token));
- if let Some(label) = label {
- string.push_str(&format!(" {}", label));
+ NodeType::Edge => {
+ write!(f, "Edge {{")?;
+ write!(
+ f,
+ "{} {} {:?}",
+ self.id,
+ self.targetid.as_ref().unwrap(),
+ self.edgetype
+ )?;
+ if let Some(label) = &self.label {
+ write!(f, " {}", label)?;
}
- string.push('}');
- write!(f, "{}", string)
+ write!(f, "}}")
}
}
}
diff --git a/src/parse/parser.rs b/src/parse/parser.rs
index e6462a0..6fd31a3 100644
--- a/src/parse/parser.rs
+++ b/src/parse/parser.rs
@@ -3,7 +3,7 @@ use crate::{
Token,
TokenType::{self, *},
},
- ContainerType, Element, StyleNode, Vis,
+ ContainerType, StyleNode, Vis, VisNode,
};
use anyhow::anyhow;
use std::collections::HashMap;
@@ -13,10 +13,21 @@ pub fn parse_vis(contents: &str) -> anyhow::Result {
// println!("{:?}", tokens);
let mut parser = Parser::new(tokens);
- Ok(Vis {
- structure: parser.structure()?,
+ let structure = parser.structure()?;
+
+ let mut vis = Vis {
+ structure: VisNode::new_node("structure", None::, structure),
styles: parser.styles()?,
- })
+ };
+
+ // add bottom up references (sorry no actual refs, but clones)
+ vis.structure.children.iter_mut().for_each(|node| {
+ let c = node.clone();
+ node.children.iter_mut().for_each(|child| {
+ child.parent.replace(c.id.to_owned());
+ });
+ });
+ Ok(vis)
}
struct Parser {
@@ -29,7 +40,7 @@ impl Parser {
Self { tokens, current: 0 }
}
- fn structure(&mut self) -> anyhow::Result> {
+ fn structure(&mut self) -> anyhow::Result> {
if self.match_token(Structure) {
self.elements()
} else {
@@ -37,7 +48,7 @@ impl Parser {
}
}
- fn elements(&mut self) -> anyhow::Result> {
+ fn elements(&mut self) -> anyhow::Result> {
// println!("nodes {:?}", self.peek());
self.consume(LeftBrace, "Expected '{'")?;
let mut nodes = vec![];
@@ -47,7 +58,7 @@ impl Parser {
Ok(nodes)
}
- fn element(&mut self) -> anyhow::Result {
+ fn element(&mut self) -> anyhow::Result {
// println!("node {:?}", self.peek());
let id = self.id()?;
// println!("id {}", id);
@@ -68,14 +79,14 @@ impl Parser {
vec![]
};
- Ok(Element::Node(id, title, children))
+ Ok(VisNode::new_node(id, title, children))
}
}
- fn edge(&mut self, from_id: String, arrow: Token) -> anyhow::Result {
+ fn edge(&mut self, from_id: String, arrow: Token) -> anyhow::Result {
let to_id = self.id()?;
let title = self.title()?;
- Ok(Element::Edge(from_id, to_id, arrow.tokentype, title))
+ Ok(VisNode::new_edge(from_id, to_id, arrow.tokentype, title))
}
fn title(&mut self) -> anyhow::Result