Comments (5)
Same as #121. :-/
from argh.
I had a little look into the code. I think there are two issues:
-
The docstring is concatenated into one big string ignoring newlines. See this code:
syn::LitStr::new(&(previous.value() + &*lit_str.value()), previous_span)
-
The printing code doesn't work quite right even if you do have newlines in the input. See this code.
Here is that code extracted with some example input.
The second issue is easy to solve. The first is more difficult because it isn't obvious when you want newlines. E.g. in this case you clearly do:
Can be one of
* A
* B
* C
But here you probably don't
There are many things
this can be including A,
B and C.
I vaguely recall some other argument parse "solving" this by letting you put {n}
for a newline, but I'm not sure I really like that. I think maybe we could get something good with one simple trick.
- Any line that starts with
[A-Za-z]
is appended to the previous line, unless the end of the output is currently\n\n
(i.e. a blank line).
I think that would correctly format something like this:
This bit is prose and should
be wrapped into a paragraph.
But this is another paragraph so there
should be a new line between
them.
1. A list would work as expected.
3. Even with long
entries like this though they
won't be wrapped nicely.
| Tables | Should |
|------|------|
| Also be | Fine |
I'll try it out.
from argh.
Ok the logic turned out to be slightly more complicated than I thought, but this seems to work:
fn parse_comment(lines: &[&str]) -> String {
let mut out = String::new();
for line in lines {
let line_starts_with_letter = line.bytes().next().map(|c| c.is_ascii_alphabetic()).unwrap_or(false);
if line_starts_with_letter {
if !out.is_empty() {
if out.ends_with('\n') {
out.push('\n');
} else {
out.push(' ');
}
}
} else {
out.push('\n');
}
out.push_str(line);
}
out
}
fn main() {
let comment = "This bit is prose and should
be wrapped into a paragraph.
But this is another paragraph so there
should be a new line between
them.
1. A list would work as expected.
3. Even with long
entries like this though they
won't be wrapped nicely.
| Tables | Should |
|------|------|
| Also be | Fine |";
let description = parse_comment(&comment.lines().collect::<Vec<_>>());
println!("{}", description);
}
Output:
This bit is prose and should be wrapped into a paragraph.
But this is another paragraph so there should be a new line between them.
1. A list would work as expected.
3. Even with long
entries like this though they
won't be wrapped nicely.
| Tables | Should |
|------|------|
| Also be | Fine |
Note the paragraphs are joined together into one line but the other bits aren't.
Now just to fix the printing code...
from argh.
Ok that turned out to be easy - just loop through the lines in the description:
for line in cmd.description.lines() {
let mut words = line.split(' ').peekable();
while let Some(first_word) = words.next() {
indent_description(&mut current_line);
current_line.push_str(first_word);
while let Some(&word) = words.peek() {
if (char_len(¤t_line) + char_len(word) + 1) > WRAP_WIDTH {
new_line(&mut current_line, out);
break;
} else {
// advance the iterator
let _ = words.next();
current_line.push(' ');
current_line.push_str(word);
}
}
}
new_line(&mut current_line, out);
}
Output is:
target This bit is prose and should be wrapped into a paragraph.
But this is another paragraph so there should be a new line
between them.
1. A list would work as expected.
3. Even with long
entries like this though they
won't be wrapped nicely.
| Tables | Should |
|------|------|
| Also be | Fine |
Note the first two paragraphs have been reflowed but everything else is left as is.
Full demo here.
I will prepare a PR if somebody from the project says they would accept it.
from argh.
Actually I went ahead and did it because I can use it without waiting for a PR to be accepted. Just add this to your Cargo.toml
:
[patch.crates-io]
argh = { git = "https://github.com/Timmmm/argh", branch = "multiline_docs" }
from argh.
Related Issues (20)
- Feature Request: choices HOT 5
- add an attribute on option argument to let `from_str_fn` can return `Vec<T>` or `Option<T>` as-is HOT 7
- how skip a field like #[serde(skip)] HOT 2
- Is it possible to get a `TopLevelCommand`'s `FieldAttrs` with the current exposed API?
- positional arguments made on field with reserved named (ref_) keep the trailing _ in help text
- Negative switches
- Subcommand with no additional arguments? HOT 1
- Impossible to include angle brackets in help text in a way that satisfies argh and rustdoc
- Change `FromArgs::from_args` to accept `AsRef<str>`
- Support something like --helpfull which displays help for all subcommands HOT 2
- `#[argh(description = "...")]` only supports literal HOT 2
- Single dash is parsed as unrecognized argument HOT 1
- Disable automatically generated help message
- mutual exclusive options/switches
- don't work as a cargo-subcommand
- Any ability to specify 'raw' greedy args or pass-through?
- Consider making serde dependency optional (as a feature) HOT 1
- Inconsistent help-related behavior around subcommands
- Document `arg_name` attribute
- Unhelpfully-aimed error-messages on subcommands
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from argh.