add chats
This commit is contained in:
parent
8f43531b47
commit
94328e0b93
12 changed files with 372 additions and 14 deletions
|
@ -291,6 +291,7 @@ impl Generator {
|
|||
treehouse,
|
||||
config,
|
||||
&mut config_derived_data,
|
||||
paths,
|
||||
parsed_tree.file_id,
|
||||
&roots.branches,
|
||||
);
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use std::fmt::Write;
|
||||
use std::{borrow::Cow, fmt::Write};
|
||||
|
||||
use pulldown_cmark::{BrokenLink, LinkType};
|
||||
use treehouse_format::pull::BranchKind;
|
||||
|
||||
use crate::{
|
||||
cli::Paths,
|
||||
config::{Config, ConfigDerivedData},
|
||||
html::EscapeAttribute,
|
||||
state::{FileId, Treehouse},
|
||||
|
@ -20,6 +21,7 @@ pub fn branch_to_html(
|
|||
treehouse: &mut Treehouse,
|
||||
config: &Config,
|
||||
config_derived_data: &mut ConfigDerivedData,
|
||||
paths: &Paths<'_>,
|
||||
file_id: FileId,
|
||||
branch_id: SemaBranchId,
|
||||
) {
|
||||
|
@ -49,6 +51,11 @@ pub fn branch_to_html(
|
|||
} else {
|
||||
"b"
|
||||
};
|
||||
let component = if !branch.attributes.cast.is_empty() {
|
||||
Cow::Owned(format!("{component} {}", branch.attributes.cast))
|
||||
} else {
|
||||
Cow::Borrowed(component)
|
||||
};
|
||||
|
||||
let linked_branch = if let Content::Link(link) = &branch.attributes.content {
|
||||
format!(" data-th-link=\"{}\"", EscapeHtml(link))
|
||||
|
@ -62,9 +69,19 @@ pub fn branch_to_html(
|
|||
""
|
||||
};
|
||||
|
||||
let mut data_attributes = String::new();
|
||||
for (key, value) in &branch.attributes.data {
|
||||
write!(
|
||||
data_attributes,
|
||||
" data-{key}=\"{}\"",
|
||||
EscapeAttribute(value)
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
write!(
|
||||
s,
|
||||
"<li data-cast=\"{component}\" class=\"{class}\" id=\"{}\"{linked_branch}{do_not_persist}>",
|
||||
"<li data-cast=\"{component}\" class=\"{class}\" id=\"{}\"{linked_branch}{do_not_persist}{data_attributes}>",
|
||||
EscapeAttribute(&branch.html_id)
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -136,7 +153,7 @@ pub fn branch_to_html(
|
|||
}
|
||||
};
|
||||
if branch.attributes.template {
|
||||
final_markdown = mini_template::render(config, treehouse, &final_markdown);
|
||||
final_markdown = mini_template::render(config, treehouse, paths, &final_markdown);
|
||||
}
|
||||
let markdown_parser = pulldown_cmark::Parser::new_with_broken_link_callback(
|
||||
&final_markdown,
|
||||
|
@ -204,7 +221,15 @@ pub fn branch_to_html(
|
|||
let num_children = branch.children.len();
|
||||
for i in 0..num_children {
|
||||
let child_id = treehouse.tree.branch(branch_id).children[i];
|
||||
branch_to_html(s, treehouse, config, config_derived_data, file_id, child_id);
|
||||
branch_to_html(
|
||||
s,
|
||||
treehouse,
|
||||
config,
|
||||
config_derived_data,
|
||||
paths,
|
||||
file_id,
|
||||
child_id,
|
||||
);
|
||||
}
|
||||
s.push_str("</ul>");
|
||||
}
|
||||
|
@ -221,12 +246,21 @@ pub fn branches_to_html(
|
|||
treehouse: &mut Treehouse,
|
||||
config: &Config,
|
||||
config_derived_data: &mut ConfigDerivedData,
|
||||
paths: &Paths<'_>,
|
||||
file_id: FileId,
|
||||
branches: &[SemaBranchId],
|
||||
) {
|
||||
s.push_str("<ul>");
|
||||
for &child in branches {
|
||||
branch_to_html(s, treehouse, config, config_derived_data, file_id, child);
|
||||
branch_to_html(
|
||||
s,
|
||||
treehouse,
|
||||
config,
|
||||
config_derived_data,
|
||||
paths,
|
||||
file_id,
|
||||
child,
|
||||
);
|
||||
}
|
||||
s.push_str("</ul>");
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Top-level `%%` root attributes.
|
||||
|
@ -79,6 +81,14 @@ pub struct Attributes {
|
|||
/// debug mode.
|
||||
#[serde(default)]
|
||||
pub stage: Stage,
|
||||
|
||||
/// List of extra spells to cast on the branch.
|
||||
#[serde(default)]
|
||||
pub cast: String,
|
||||
|
||||
/// List of extra `data` attributes to add to the block.
|
||||
#[serde(default)]
|
||||
pub data: HashMap<String, String>,
|
||||
}
|
||||
|
||||
/// Controls for block content presentation.
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::ops::Range;
|
|||
|
||||
use pulldown_cmark::escape::escape_html;
|
||||
|
||||
use crate::{config::Config, state::Treehouse};
|
||||
use crate::{cli::Paths, config::Config, state::Treehouse};
|
||||
|
||||
struct Lexer<'a> {
|
||||
input: &'a str,
|
||||
|
@ -149,7 +149,7 @@ impl<'a> Renderer<'a> {
|
|||
self.output.push_str(&self.lexer.input[token.range.clone()]);
|
||||
}
|
||||
|
||||
fn render(&mut self, config: &Config, treehouse: &Treehouse) {
|
||||
fn render(&mut self, config: &Config, treehouse: &Treehouse, paths: &Paths<'_>) {
|
||||
let kind_of = |token: &Token| token.kind;
|
||||
|
||||
while let Some(token) = self.lexer.next() {
|
||||
|
@ -166,6 +166,7 @@ impl<'a> Renderer<'a> {
|
|||
match Self::render_template(
|
||||
config,
|
||||
treehouse,
|
||||
paths,
|
||||
self.lexer.input[inside.as_ref().unwrap().range.clone()].trim(),
|
||||
) {
|
||||
Ok(s) => match escaping {
|
||||
|
@ -192,22 +193,24 @@ impl<'a> Renderer<'a> {
|
|||
fn render_template(
|
||||
config: &Config,
|
||||
_treehouse: &Treehouse,
|
||||
paths: &Paths<'_>,
|
||||
template: &str,
|
||||
) -> Result<String, InvalidTemplate> {
|
||||
let (function, arguments) = template.split_once(' ').unwrap_or((template, ""));
|
||||
match function {
|
||||
"pic" => Ok(config.pic_url(arguments)),
|
||||
"c++" => Ok("<script>alert(1)</script>".into()),
|
||||
"include_static" => std::fs::read_to_string(paths.static_dir.join(arguments))
|
||||
.map_err(|_| InvalidTemplate),
|
||||
_ => Err(InvalidTemplate),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(config: &Config, treehouse: &Treehouse, input: &str) -> String {
|
||||
pub fn render(config: &Config, treehouse: &Treehouse, paths: &Paths<'_>, input: &str) -> String {
|
||||
let mut renderer = Renderer {
|
||||
lexer: Lexer::new(input),
|
||||
output: String::new(),
|
||||
};
|
||||
renderer.render(config, treehouse);
|
||||
renderer.render(config, treehouse, paths);
|
||||
renderer.output
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue