//! In-app **Markdown cheatsheet** window: a quick reference for the markdown //! md-manuscript understands, plus the manuscript-specific conventions (chapter //! metadata, the draft-marker header, and comments) applied at export time. //! //! Pure rendering — the caller owns the `open` flag so the window's ✕ works via //! [`egui::Window::open`]. use eframe::egui; /// The Markdown syntax cheatsheet window. pub fn cheatsheet_window(ctx: &egui::Context, open: &mut bool) { egui::Window::new("📝 Markdown Cheatsheet") .open(open) .resizable(true) .default_width(560.0) .default_height(560.0) .show(ctx, |ui| { egui::ScrollArea::vertical().show(ui, cheatsheet_body); }); } fn cheatsheet_body(ui: &mut egui::Ui) { intro( ui, "The markdown md-manuscript renders on export. Left column is what you type.", ); section(ui, "Headings"); syntax( ui, "cs-headings", &[ ("# Heading", "A top-level heading (nested under the chapter title on export)."), ("## Sub-heading", "A second-level heading; deeper levels use more #."), ], ); note( ui, "On export, every heading is pushed down one level so it sits beneath the \ chapter's own title. See “Chapter metadata” below for setting that title.", ); section(ui, "Emphasis & inline"); syntax( ui, "cs-inline", &[ ("**bold**", "Bold text."), ("*italic*", "Italic text (also _italic_)."), ("***bold italic***", "Both at once."), ("~~strike~~", "Strikethrough."), ("`code`", "Inline monospaced code."), ("[text](https://url)", "A hyperlink."), ], ); section(ui, "Formatting hotkeys"); syntax( ui, "cs-keys", &[ ("Ctrl/Cmd + B", "Bold the selection (**…**)."), ("Ctrl/Cmd + I", "Italicise the selection (*…*)."), ("Ctrl/Cmd + E", "Inline code (`…`)."), ("Ctrl/Cmd + Shift + X", "Strikethrough (~~…~~)."), ("Ctrl/Cmd + K", "Wrap as a link and select the url to replace."), ("Ctrl/Cmd + F", "Open the find bar."), ("Ctrl/Cmd + H", "Open find/replace (replace field focused)."), ], ); note( ui, "Wrapping keys apply to the selected text (or the caret, for an empty \ selection); pressing the same key on already-wrapped text removes the \ markers. In the find bar, Enter / Shift+Enter step through matches and \ Esc closes it.", ); section(ui, "Paragraphs & breaks"); syntax( ui, "cs-para", &[ ("blank line", "Separates paragraphs."), ("--- (on its own line)", "A horizontal rule — handy as a scene break."), ], ); section(ui, "Lists"); syntax( ui, "cs-lists", &[ ("- item", "An unordered list item (also * item or + item)."), (" - nested", "Indent two spaces to nest a sub-item."), ("1. item", "An ordered (numbered) list item."), ("> quote", "A blockquote."), ], ); section(ui, "Code blocks"); syntax( ui, "cs-code", &[ ("```", "Open and close a fenced code block on their own lines."), (" four-space indent", "An indented code block."), ], ); section(ui, "Chapter metadata"); syntax( ui, "cs-meta", &[ ("# Title: Chapter Name", "Sets this file's chapter heading on export."), ("# Slug: a caption", "A caption shown beneath the chapter title."), ], ); note( ui, "These lines are lifted out and removed from the exported prose. Without a \ # Title:, the chapter falls back to a manual override (the title field) or \ its position number.", ); section(ui, "Editorial header & comments"); syntax( ui, "cs-header", &[ ("### Rough Draft:", "The draft marker — everything above it is your working header."), ("", "A comment; dropped on export (may span multiple lines)."), ], ); note( ui, "The draft marker text is configurable in the top bar. Everything above the \ marker line is treated as notes and left out of the export; leave the marker \ blank to export the whole file. Comments are removed everywhere.", ); section(ui, "Grammar & spelling"); body( ui, "Press ✓ Check (or the Grammar panel) to run the current file through your \ LanguageTool server — configure it in Settings ▸ LanguageTool. Spelling issues \ are underlined in red, grammar/style in blue.", ); } // --- small rendering helpers -------------------------------------------------- fn intro(ui: &mut egui::Ui, text: &str) { ui.label(egui::RichText::new(text).italics().weak()); ui.add_space(4.0); } fn section(ui: &mut egui::Ui, title: &str) { ui.add_space(8.0); ui.heading(title); ui.separator(); } fn body(ui: &mut egui::Ui, text: &str) { ui.label(text); } fn note(ui: &mut egui::Ui, text: &str) { ui.add_space(2.0); ui.label(egui::RichText::new(format!("ⓘ {text}")).small().weak()); } /// A two-column grid of `syntax/meaning` rows (syntax in a highlighted monospace). fn syntax(ui: &mut egui::Ui, id: &str, rows: &[(&str, &str)]) { egui::Grid::new(id) .num_columns(2) .striped(true) .spacing([18.0, 4.0]) .show(ui, |ui| { for (s, v) in rows { ui.label( egui::RichText::new(*s) .monospace() .color(egui::Color32::from_rgb(120, 170, 120)), ); ui.label(*v); ui.end_row(); } }); }