use crate::recipe::Recipe;
pub fn emit_cook(recipe: &Recipe) -> String {
if let Some(ref source) = recipe.raw_source {
return source.clone();
}
let mut out = String::new();
out.push_str("---\n");
out.push_str(&format!("title: {}\n", recipe.title));
if let Some(ref s) = recipe.source {
out.push_str(&format!("source: {s}\n"));
}
if let Some(ref s) = recipe.source_url {
out.push_str(&format!("source url: {s}\n"));
}
if let Some(ref s) = recipe.servings {
out.push_str(&format!("servings: {s}\n"));
}
if let Some(ref s) = recipe.recipe_yield {
out.push_str(&format!("yield: {s}\n"));
}
if let Some(ref s) = recipe.prep_time {
out.push_str(&format!("prep time: {s}\n"));
}
if let Some(ref s) = recipe.cook_time {
out.push_str(&format!("cook time: {s}\n"));
}
if let Some(ref s) = recipe.total_time {
out.push_str(&format!("total time: {s}\n"));
}
if let Some(ref s) = recipe.description {
out.push_str(&format!("description: {s}\n"));
}
if !recipe.tags.is_empty() {
out.push_str(&format!("tags: {}\n", recipe.tags.join(", ")));
}
out.push_str("---\n\n");
let mut current_section: Option<&str> = None;
for step in &recipe.steps {
let step_section = step.section.as_deref();
if step_section != current_section {
if let Some(name) = step_section
&& !name.is_empty()
{
out.push_str(&format!("== {name} ==\n\n"));
}
current_section = step_section;
}
out.push_str(&emit_step_text(recipe, step));
out.push_str("\n\n");
}
out.trim_end().to_string() + "\n"
}
fn emit_step_text(recipe: &Recipe, step: &crate::recipe::Step) -> String {
let mut text = step.body.clone();
for ing in &recipe.ingredients {
if let Some(pos) = text.find(&ing.name) {
let annotation = format_ingredient(ing);
text = format!(
"{}{}{}",
&text[..pos],
annotation,
&text[pos + ing.name.len()..]
);
}
}
text
}
fn format_ingredient(ing: &crate::recipe::RecipeIngredient) -> String {
match (&ing.quantity, &ing.unit) {
(Some(qty), Some(unit)) => format!("@{}{{{}%{}}}", ing.name, qty, unit),
(Some(qty), None) => format!("@{}{{{}}} ", ing.name, qty),
_ => format!("@{}{{}}", ing.name),
}
}