diff --git a/src/handlers/graph.rs b/src/handlers/graph.rs index 8b16b69..d8120f3 100644 --- a/src/handlers/graph.rs +++ b/src/handlers/graph.rs @@ -12,10 +12,13 @@ pub async fn node(Path(id): Path) -> Response { context.insert("id", &id); context.insert("title", &node.title); - context.insert("text", &node.text); context.insert("connections", &node.connections.clone()); context.insert("incoming", &graph.incoming.get(&id)); + let escaped_text = tera::escape_html(&node.text); + let out_text = crate::syntax::content::parse(&escaped_text); + context.insert("text", &out_text); + let not_found = node.clone() == empty_node; let template_name = "node.html".to_string(); diff --git a/src/syntax.rs b/src/syntax.rs index d08cc22..caef4dc 100644 --- a/src/syntax.rs +++ b/src/syntax.rs @@ -1 +1,2 @@ pub mod arguments; +pub mod content; diff --git a/src/syntax/content.rs b/src/syntax/content.rs new file mode 100644 index 0000000..3dba7c9 --- /dev/null +++ b/src/syntax/content.rs @@ -0,0 +1,57 @@ +use std::fmt::Write as _; +use crate::dev::log; + +pub fn parse(text: &str) -> String { + let mut out_text: Vec = Vec::new(); + + for line in text.lines() { + if line.is_empty() || line.replace(" ", "").is_empty() { + continue; + } + + let mut out_line: String = line.to_owned(); + let words: Vec = line.split(" ").map(str::to_string).collect(); + let first_word: &String = + words.first().unwrap_or_else(|| unreachable!()); + + if is_header(first_word) { + out_line = parse_header(&out_line, first_word); + } + // if not special, default to treating line as a paragraph + else { + out_line.insert_str(0, "

"); + out_line.push_str("

"); + } + + out_text.push(out_line); + } + + out_text.join("\n") +} + +fn is_header(lexeme: &str) -> bool { + !lexeme.trim().is_empty() + && lexeme.replace("#", "").is_empty() + && lexeme.len() <= 6 +} + +fn parse_header(line: &str, first_word: &str) -> String { + log(&parse_header, &format!("Parsing: {line:?}")); + + let header_level = first_word.len(); + log(&parse, &format!("Header level is {header_level}")); + let header_text = line.to_owned().replace(first_word, ""); + let mut w = String::with_capacity(header_text.len().strict_add(9)); + let alloc = w.capacity(); + match write!(w, "{header_text}") { + Ok(()) => (), + Err(e) => panic!("{e:?}"), + } + if alloc != w.capacity() { + log( + &parse_header, + &format!("w reallocated to {} despite prediction", w.capacity()), + ); + } + w +} diff --git a/static/graph.toml b/static/graph.toml index 78a3053..a3bdfe1 100644 --- a/static/graph.toml +++ b/static/graph.toml @@ -3,7 +3,7 @@ root_node = "Documentation" [nodes.Documentation] text = """ -Installation +## Installation For now, if you want to try en, you must build it yourself. @@ -15,7 +15,7 @@ cargo build --release The en binary will be in target/release/en. -Graph Syntax +## Graph Syntax The graph is a TOML file. You can create nodes by adding text such as: @@ -31,7 +31,8 @@ A computer is a machine capable of executing arbitrary instructions. Nodes can have connections between each other. -To add a simple connection without any associated properties, you can simply add links: +To add a simple connection without any associated properties, you can simply +add links: [nodes.Quark] text = "A subatomic particle that forms hadrons." @@ -40,7 +41,7 @@ links = [ "Particle", "Hadron" ] This will create two outgoing connections from Quark: to Particle and to Hadron. It will also list Quark as an incoming connection in these nodes' pages. - If you want to add properties to the connection, you can use the connection syntax: +If you want to add properties to the connection, you can use the connection syntax: [[nodes.Quark.connections]] to = "Particle physics" @@ -48,7 +49,7 @@ anchor = "particle" This will create a connection from Quark to "Particle physics", and the first occurrence of the word "particle" in the text of Quark gets anchored to this connection. -CLI Options +## CLI Options You can set the hostname, port and graph file path using CLI options: diff --git a/templates/node.html b/templates/node.html index cd7f759..6a6e39a 100644 --- a/templates/node.html +++ b/templates/node.html @@ -6,9 +6,7 @@

{{ title }}

ID: {{ id }} - {% for line in text | split(pat="\n") %} - {% if line %}

{{ line }}

{% endif %} - {% endfor %} + {{ text | safe }}
{% if connections or incoming %}