-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ManSection enum, own title line struct and other minor updates #14
Conversation
### Created by https://www.gitignore.io | ||
### Rust ### | ||
# Generated by Cargo | ||
# will have compiled files and executables | ||
debug/ | ||
target/ | ||
|
||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries | ||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html | ||
Cargo.lock | ||
|
||
# These are backup files generated by rustfmt | ||
**/*.rs.bk | ||
|
||
# MSVC Windows builds of rustc generate these, which store debugging information | ||
*.pdb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come you are changing the .gitignore
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Force of habit, it carried over from my previous work on roff-rs
, I can revert this if you want to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do so. imo person/machine specific ignores should be set in the personal ignores rather than checked into the shared ignores.
/// Manpage sections. | ||
/// | ||
/// The most common is [`ManSection::Executable`], and is the recommended default. | ||
#[derive(Clone, Copy)] | ||
pub enum ManSection { | ||
/// Executable programs or shell commands | ||
Executable, | ||
/// System calls (functions provided by the kernel) | ||
SystemCalls, | ||
/// Library calls (functions within program libraries) | ||
LibraryCalls, | ||
/// Special files (usually found in /dev) | ||
SpecialFiles, | ||
/// File formats and conventions, e.g. /etc/passwd | ||
FileFormats, | ||
/// Games | ||
Games, | ||
/// Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7) | ||
Miscellaneous, | ||
/// System administration commands (usually only for root) | ||
SystemAdministrationCommands, | ||
/// Kernel routines [Non standard] | ||
KernelRoutines, | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I'm missing something, this seems like man policy when this crate is focused on the underlying markup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your two comments about whether things should go here or in a more manpage specific crate was one of the reasons I ended up trying to do everything in
clap_man
, the inclusion of a title line means we're already targeting manpages and not "pure"roff
. It is a massive type-setting system (here is short reference of GNU variant of the format, you can see we're only really touching a tiny, tiny part of it), and has historically been used for lots of different things from books, articles and more.Nowadays however I thing nobody uses it outside of manpages anymore, and while the
man
crate contains useful tools to build manpages for CLI tools this crate already targets a subset ofroff
specific to manpages, at least in my opinion. sweat_smileroffman
that you mentioned in the PR inclap
has sections in it, though the name implies that it is specific for manpages, but not a huge fan of its API.Sorry, this is a lot of words for saying that in my head
roff-rs
is already a manpage specific crate slightly_smiling_face It's again one of the reasons I've attempted a few different approaches to this, I haven't found a good solution for it yet besides creating my own crate for this.
My thought is to prefer to keep this crate man agnostic unless its getting in the way of getting clap_man
done.
It looks like we could have the Section enum and the title formatting external to this crate and lose nothing but I'm not as knee deep in both crates as you are, so I defer to your judgement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to the current architecture this crate cannot be used to create anything besides manpages, so it is in a sense already specific to manpages and not agnostic. I'm starting to lean more towards having a more intermediate crate specifically for creating manpages, I have a prototype laying around that I could revive. Thoughts?
/// Date of the last nontrivial change to the manpage. Should be formatted | ||
/// in `YYYY-MM-DD`. | ||
pub fn date(mut self, date: impl Into<String>) -> Self { | ||
self.title.date = Some(date.into()); | ||
self | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we accept year, month, day
arguments so we can enforce formatting or eventually add a date/time lib dependency (haven't looked to see where the community is at with time vs chrono)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's probably a better way of doing it, good point. Not sure I'd like to pull in a full library for date changes here, we might do it in clap_man
instead to fill these in instead.
} | ||
} | ||
|
||
pub struct Roff { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Roff
is the entry point for this crate. please keep it first in the file so its easier to jump in and see what this crate does
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix!
pub struct Title { | ||
title: String, | ||
section: i8, | ||
section: ManSection, | ||
date: Option<String>, | ||
source: Option<String>, | ||
manual: Option<String>, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much of this is roff vs man policy?
#[derive(PartialEq, Eq)] | ||
pub struct Roff { | ||
/// Title line for a manpage. | ||
pub struct Title { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should at least implement Debug
and Clone
on everything
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point!
@@ -48,7 +148,6 @@ impl Troffable for Roff { | |||
} | |||
} | |||
|
|||
#[derive(PartialEq, Eq)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come you've been dropping PartialEq, Eq
from these items?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really know why it's derived, I can't imagine it was used for something besides testing (the first full commit has them derived but not used) because comparing manpages for equality sounds very niche.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I lean towards keeping them (slightly less important than Clone
and Debug
) though we should make sure we call this out as a breaking change.
pub fn escape(input: &str) -> String { | ||
input.replace("-", r"\-") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is escape
public? It seems like the API should be enforcing whats escaped or not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was an oversight on my part, I forgot that everything is escaped when rendered, I'll fix this.
Your two comments about whether things should go here or in a more manpage specific crate was one of the reasons I ended up trying to do everything in Nowadays however I thing nobody uses it outside of manpages anymore, and while the Sorry, this is a lot of words for saying that in my head |
@@ -109,7 +109,7 @@ impl Troffable for Section { | |||
fn render(&self) -> String { | |||
let mut res = String::new(); | |||
|
|||
writeln!(&mut res, ".SH {}", self.title.to_uppercase()).unwrap(); | |||
writeln!(&mut res, ".SH \"{}\"", self.title.to_uppercase()).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will fail if the title contains quote characters. I'm not sure how to fix that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oddly, I'm not seeing any quote escaping in asciidoctor, only left/right quotes. I wonder if that is an artifact of them only using left/right quotes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some more information on escaping, check out https://www.ibm.com/docs/en/aix/7.2?topic=t-troff-command (search for mm Strings)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been reading the groff(7), and I can't see any way to escape quotes in control lines or macro arguments.
@@ -130,6 +130,16 @@ impl Troffable for Roff { | |||
|
|||
writeln!(&mut res, "{}", self.title.render()).unwrap(); | |||
|
|||
// Compatibility settings: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this needed? What requires turning of justification and hyphenation?
I'm looking at this from a manual page generation point of view, and non-justified manual pages are unusual, and thus jarring to read. I could live with it, but I'd like the comment to explain what requires it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the topic of compat settings, asciidoctor does https://github.com/asciidoctor/asciidoctor/blob/main/lib/asciidoctor/converter/manpage.rb#L61 (with links out for information)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point about plain apostrophes is a good one, and I should add that to my roff crate version. However, I can't see any explanation of why hyphenation and justification should be turned off. The sentence space size I can live with: it removes the need to make sure sentences end with a newline after the terminating punctuation.
I had a closer look at the manual page generation and the roff crate. I've pushed two branches that I think would be an improvement. https://github.com/larswirzenius/roff-rs/tree/liw/roff-only changes roff to have an abstraction level of ROFF only, dropping manual page stuff. The commit message has some more detailed explanations. The branch isn't ready to be merged, and needs some cleanup first. I then ported @sondr3's What do you think? Is my approach of any interest? |
I really like this! By focusing on the roff structure, I feel like it makes clearer the intent of what is going on while giving the benefit of escaping and typing (compared to doing everything with raw strings). |
I too like your approach and from the comment over on the PR to clap you have far more experience working with manpages and the roff-format, so you can be the judge for this crate. Do you want to create a PR against my fork of clap so we can integrate your changes once you feel it's ready? 😄 |
I will do that later today or tomorrow, as soon as I've dug myself out from this horde of elves I'm buried under. |
Superseded by #15. |
The title line, manpage section and compatibility settings come from clap-rs/clap#3174, where we decided on extracting out Roff-specific functionality to this crate. I also did a few minor changes, like removing the derive for
PartialEq
andEq
from the structs. The title line struct will make #7 obsolete, and is in my opinion a better solution as the order of the elements is important and is not just a list of strings.cc @epage