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:
@@ -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
@@ -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
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
mod app;
|
||||
mod config;
|
||||
mod gitsync;
|
||||
mod help;
|
||||
mod langtool;
|
||||
mod odt;
|
||||
mod order;
|
||||
|
||||
Reference in New Issue
Block a user