diff --git a/README.md b/README.md index 26a8ca4..9191ac3 100644 --- a/README.md +++ b/README.md @@ -181,3 +181,7 @@ Headings, paragraphs, **bold**, *italic*, ***both***, `inline code`, fenced/inde code blocks (monospace, whitespace preserved), ~~strikethrough~~, ordered and unordered (nested) lists, block quotes, horizontal rules, and links. Images are rendered as a text placeholder (not embedded). + +A quick reference for all of this — plus the chapter metadata, draft-marker +header, and comment conventions — is built in: open **Help ▸ Markdown cheatsheet** +from the menu bar. diff --git a/src/app.rs b/src/app.rs index 6eb0db3..811bd45 100644 --- a/src/app.rs +++ b/src/app.rs @@ -63,6 +63,8 @@ pub struct App { settings_test_rx: Option>>, /// Result line for the settings window's "Test connection" button. settings_test_status: String, + /// Whether the markdown cheatsheet window is open. + show_cheatsheet: bool, } impl App { @@ -96,6 +98,7 @@ impl App { show_settings: false, settings_test_rx: None, settings_test_status: String::new(), + show_cheatsheet: false, }; app.open_workspace(); app @@ -969,6 +972,12 @@ impl App { self.show_settings = true; } }); + ui.menu_button("Help", |ui| { + if ui.button("📝 Markdown cheatsheet").clicked() { + ui.close_menu(); + self.show_cheatsheet = true; + } + }); }); }); } @@ -1411,6 +1420,10 @@ impl eframe::App for App { self.settings_window(ctx); } + if self.show_cheatsheet { + crate::help::cheatsheet_window(ctx, &mut self.show_cheatsheet); + } + if self.pending_repo.is_some() { self.repo_prompt(ctx); } diff --git a/src/help.rs b/src/help.rs new file mode 100644 index 0000000..49eca28 --- /dev/null +++ b/src/help.rs @@ -0,0 +1,169 @@ +//! 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, "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(); + } + }); +} diff --git a/src/main.rs b/src/main.rs index d47537f..446a1fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod app; mod config; mod gitsync; +mod help; mod langtool; mod odt; mod order;