Add a Help menu with a built-in Markdown cheatsheet

Mirrors the logrs cheatsheet: a scrollable reference window covering the
markdown md-manuscript renders on export, plus the manuscript-specific
conventions (# Title:/# Slug: metadata, the draft-marker header, and
comments). Opened from Help ▸ Markdown cheatsheet in the menu bar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
landon
2026-07-29 10:49:13 -05:00
parent b31ac0c6c8
commit 503ef4f24a
4 changed files with 187 additions and 0 deletions
+4
View File
@@ -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.
+13
View File
@@ -63,6 +63,8 @@ pub struct App {
settings_test_rx: Option<std::sync::mpsc::Receiver<Result<usize, String>>>,
/// 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);
}
+169
View File
@@ -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."),
("<!-- note -->", "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();
}
});
}
+1
View File
@@ -5,6 +5,7 @@
mod app;
mod config;
mod gitsync;
mod help;
mod langtool;
mod odt;
mod order;