Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion docs/src/features/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,25 @@ centered
right aligned
```


## User comments

User comments such as personal notes, TODOs, and other documentation that will
be ignored during presentation rendering can be added using these formats:

```markdown
<!-- // This is a user comment -->
<!-- comment: This is also a user comment which won't be rendered -->
```
These comments are completely invisible during presentation and useful for:

- Personal notes and reminders
- TODO items and planning notes
- Source references and attribution




## Listing available comment commands

The `--list-comment-commands` CLI option outputs all available comment commands to stdout, making it easy to discover and use them in external tools and editors.
Expand Down Expand Up @@ -216,4 +235,3 @@ endif
```

With this configuration, pressing `Ctrl+K` in insert mode will open an fzf picker with all available comment commands, allowing you to quickly select and insert them into your presentation.

1 change: 0 additions & 1 deletion examples/demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ author: Matias

Customizability
---

_presenterm_ allows configuring almost anything about your presentation:

* The colors used.
Expand Down
10 changes: 9 additions & 1 deletion src/presentation/builder/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ impl PresentationBuilder<'_, '_> {
Err(error) => {
// If we failed to parse this, make sure we shouldn't have ignored it
if self.should_ignore_comment(comment) {
// Ignored comments should not add line breaks
self.slide_state.ignore_element_line_break = true;
Comment on lines 16 to +20
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With command_prefix configured, valid commands that do not start with the prefix can still be parsed/executed because parsing happens before this error branch and only falls back to should_ignore_comment when parsing fails. This contradicts the documented behavior of command_prefix (docs/src/configuration/options.md). Consider enforcing the prefix before attempting to parse (or update docs/tests to reflect the intended semantics).

Copilot uses AI. Check for mistakes.
return Ok(());
}
Comment on lines 18 to 22
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the extra newline issue for ignored comments by setting ignore_element_line_break, but there isn’t a regression test asserting the rendered output doesn’t gain a blank line when an ignored comment appears between two rendered elements. Adding a render-based test (e.g., text + ignored comment + text) would help prevent reintroducing this behavior.

Copilot uses AI. Check for mistakes.
return Err(self.invalid_presentation(source_position, error));
Expand All @@ -42,6 +44,7 @@ impl PresentationBuilder<'_, '_> {
CommentCommand::NewLines(count) => {
self.push_line_breaks(count as usize * self.slide_font_size() as usize);
}
CommentCommand::Comment(_) => {}
CommentCommand::JumpToMiddle => self.chunk_operations.push(RenderOperation::JumpToVerticalCenter),
CommentCommand::InitColumnLayout(columns) => {
self.validate_column_layout(&columns, source_position)?;
Expand Down Expand Up @@ -149,7 +152,7 @@ impl PresentationBuilder<'_, '_> {
} else {
// Ignore vim-like code folding tags
let comment = comment.trim();
comment == "{{{" || comment == "}}}"
comment == "{{{" || comment == "}}}" || comment.starts_with("//")
}
}

Expand Down Expand Up @@ -205,6 +208,7 @@ pub(crate) enum CommentCommand {
SkipSlide,
SpeakerNote(String),
SnippetOutput(String),
Comment(String),
}
Comment on lines 208 to 212
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CommentCommand::Comment is now a parseable command, but CommentCommand::generate_samples() (used by --list-comment-commands) still claims to generate samples for “all available commands” and doesn’t include comment. Either add a sample for comment: to keep the listing complete, or adjust the wording/approach so user comments aren’t treated as a command.

Copilot uses AI. Check for mistakes.

impl CommentCommand {
Expand Down Expand Up @@ -290,6 +294,7 @@ mod tests {
#[case::incremental_lists("newlines: 2", CommentCommand::NewLines(2))]
#[case::incremental_lists("new_line", CommentCommand::NewLine)]
#[case::incremental_lists("newline", CommentCommand::NewLine)]
#[case::comment("comment: This is a user comment", CommentCommand::Comment("This is a user comment".into()))]
fn command_formatting(#[case] input: &str, #[case] expected: CommentCommand) {
let parsed: CommentCommand = input.parse().expect("deserialization failed");
assert_eq!(parsed, expected);
Expand All @@ -301,6 +306,9 @@ mod tests {
#[case::many_close_braces("}}}")]
#[case::vim_command("vim: hi")]
#[case::padded_vim_command("vim: hi")]
#[case::double_slash("// This is a user comment")]
#[case::double_slash_padded(" // This is a padded comment ")]
#[case::comment_colon("comment: This is a user comment")]
fn ignore_comments(#[case] comment: &str) {
let input = format!("<!-- {comment} -->");
Test::new(input).build();
Expand Down
Loading