Skip to content
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

Improve usage documentation and break synopsis lines to fit terminal #4796

Merged
merged 83 commits into from
Jun 16, 2021

Conversation

PaulWessel
Copy link
Member

See #4762 for background. This PR adds a new testbreak.c program that can be used for exploring auto-breaking. Since it is not a GMT module, it gets built and placed in build/src so you need to run it from there. Its syntax is

testbreak [length [-]]

Here, length is the nominal width of the synopsis output [80]. If you give a length then you may also give an optional - to select @KristofKoch's fancy UTF-8 carriage-return symbol ⏎ for line continuation; otherwise you get @joa-quim's sad .....
Behavior: We try to make output records around the length. If adding the next word greatly exceeds length then we try to break it at a ] and append a "line to be continued" marker, and indent 2 spaces on the continuation line.

Examples:

testbreak

WRAP: 80 characters

usage: somemodule <grid> [-A] [-C] [-D[+x<xname>][+y<yname>][+d<dname>][+s<scale>]...
	  ...[+o<offset>][+n<invalid>][+t<title>][+r<remark>][+v<name>]] [-E[a|e|h|l|r|t|v]] 
	[-G<outgrid>] [-J<args>] [-L[+n|p]] [-N<table>] 
	[-R<west>/<east>/<south>/<north>[+r]] [-S] [-T] [-V[<level>]] 
	[-bi[<ncol>][t][w][+l|b]] [-di<nodata>] [-e[~]<pattern>] [-f[i|o]<info>] [-h[i|o]...
	  ...[<nrecs>][+c][+d][+m<segheader>][+r<remark>][+t<title>]] [-i<cols>[+l][+d<divide>]...
	  ...[+s<scale>][+o<offset>][,...][,t[<word>]]] 
	[-wa|y|w|d|p<period][/<phase>][+c<col>]] [-:[i|o]] [--PAR=<value>]

testbreak 100 -

WRAP: 100 characters

usage: somemodule <grid> [-A] [-C] [-D[+x<xname>][+y<yname>][+d<dname>][+s<scale>][+o<offset>][+n<invalid>]⏎
	  [+t<title>][+r<remark>][+v<name>]] [-E[a|e|h|l|r|t|v]] [-G<outgrid>] [-J<args>] [-L[+n|p]] 
	[-N<table>] [-R<west>/<east>/<south>/<north>[+r]] [-S] [-T] [-V[<level>]] [-bi[<ncol>][t][w][+l|b]] 
	[-di<nodata>] [-e[~]<pattern>] [-f[i|o]<info>] [-h[i|o][<nrecs>][+c][+d][+m<segheader>][+r<remark>]⏎
	  [+t<title>]] [-i<cols>[+l][+d<divide>][+s<scale>][+o<offset>][,...][,t[<word>]]] [-wa|y|w|d|p<period]⏎
	  [/<phase>][+c<col>]] [-:[i|o]] [--PAR=<value>]

The idea is that we would just make one lone text string at top of each usage() function then call this gmt_usage_line function to display according to our width rules. It could even be a GMT parameter [GMT_SYNOPSIS_WIDTH = 120].

New testbreak.c program used for exploring auto-breaking.
@PaulWessel PaulWessel requested review from KristofKoch and a team February 12, 2021 03:36
@PaulWessel
Copy link
Member Author

Does anyone find this test useful and have suggestions for improvements? @KristofKoch ? @joa-quim ?

@joa-quim
Copy link
Member

Did not play with this yet.

@KristofKoch
Copy link
Contributor

Surely a beginners question – but how do I start the program?

@joa-quim
Copy link
Member

After building from this branch just type testbreak in the command line.

@KristofKoch
Copy link
Contributor

Mh, then I'm doing something wrong:

$ gmt --version
6.2.0_0545e0a_2021.02.11
$ testbreak
-bash: testbreak: command not found
$ gmt testbreak

ERROR: No module named testbreak was found. […]

@PaulWessel
Copy link
Member Author

Remember the binary is in build/src which is probably not in your path. It is not a gmt module.

@PaulWessel
Copy link
Member Author

OK, looks like nobody gave this a spin. Given we have a lot of hideously formatted usage messages like

usage: gmt velo [<table>] -J<args> -R<west>/<east>/<south>/<north>[+r] [-A<vecpar>] [-B<args>] [-D<sigscale>]
	[-G<fill>] [-L] [-N] [-S<symbol><args>[+f<font>]]
	[-U[<label>][+c][+j<just>][+o<dx>/<dy>]] [-V] [-W<pen>] [-X[a|c|f|r]<xshift>]
	[-Y[a|c|f|r]<yshift>] [-c[<row>,<col>|<index>]] [-di<nodata>] [-e[~]<pattern>] [-h[i|o][<nrecs>][+c][+d][+m<segheader>][+r<remark>][+t<title>]]
	[-i<cols>[+l][+d<divide>][+s<scale>][+o<offset>][,...][,t[<word>]]] [-p[x|y|z]<azim>[/<elev>[/<zlevel>]][+w<lon0>/<lat0>[/<z0>][+v<x0>/<y0>]]
	[-qi[~]<rows>[,...][+c<col>][+a|f|s]] [-t<transp>[/<transp2>[+f|s]] [-:[i|o]] [--PAR=<value>]

and 150 of these, it seems something automatic and configurable is better than manual grunt work that has to be updated each time another option is added? Please give it a try and see if you think this is an improvement. Adding @GenericMappingTools/core now since I forgot.

@maxrjones
Copy link
Member

If this gets converted to a GMT_Wrap function, could it be implemented for users to define their preferred default message line length in ConfigUserAdvanced.cmake?

@PaulWessel
Copy link
Member Author

Sure, if we decide that adding a new defaults like GMT_SYNOPSIS_WIDTH is too much tinkering then we can make that a CMake setting instead with our final default value [say 120].

@maxrjones
Copy link
Member

Sure, if we decide that adding a new defaults like GMT_SYNOPSIS_WIDTH is too much tinkering then we can make that a CMake setting instead with our final default value [say 120].

Either way seems fine. Will gmt_usage_line work for the detailed option descriptions in addition to the synopsis or will that require a separate function? Also, did you base the example synopsis in testbreak.c on any particular GMT module? I am interested in comparing the testbreak output to the current GMT output.

@PaulWessel
Copy link
Member Author

Looks like it was based on grdedit. This was only for the synopsis. The individual descriptions is tricker because some are done by a functino and others are inline. But perhaps that can still be handled and the break-function could be told to honor \n to break when we want to break, etc.

@maxrjones
Copy link
Member

maxrjones commented Feb 27, 2021

Looks like it was based on grdedit. This was only for the synopsis. The individual descriptions is tricker because some are done by a functino and others are inline. But perhaps that can still be handled and the break-function could be told to honor \n to break when we want to break, etc.

Thanks for the explanation. This is nice, I think that giving the user the ability to define their preferred message length is a worthwhile improvement. When the ⏎ symbol is not used, I find it slightly more readable to use only three periods on the continued line, rather than two spaces and three periods.
For reference, here is with one tab and three periods for continuations and an 92 character line length:

usage: somemodule <grid> [-A] [-C] [-D[+x<xname>][+y<yname>][+d<dname>][+s<scale>][+o<offset>]...
	...[+n<invalid>][+t<title>][+r<remark>][+v<name>]] [-E[a|e|h|l|r|t|v]] [-G<outgrid>] [-J<args>] 
	[-L[+n|p]] [-N<table>] [-R<west>/<east>/<south>/<north>[+r]] [-S] [-T] [-V[<level>]] 
	[-bi[<ncol>][t][w][+l|b]] [-di<nodata>] [-e[~]<pattern>] [-f[i|o]<info>] [-h[i|o][<nrecs>]...
	...[+c][+d][+m<segheader>][+r<remark>][+t<title>]] [-i<cols>[+l][+d<divide>][+s<scale>][+o<offset>]...
	...[,...][,t[<word>]]] [-wa|y|w|d|p<period][/<phase>][+c<col>]] [-:[i|o]] [--PAR=<value>]

It will still be necessary to define the preferred line length for the reformatted synopsis and long descriptions in the source code if GMT_Message() gets refactored to GMT_Wrap() in some places; it would be nice to close this issue at the same time by adding the decided convention to CODE_CONVENTIONS.md. I agree with @joa-quim's suggestion of 120-130 chars.

@PaulWessel
Copy link
Member Author

Yes, I agree. 120-130 is probably good, but once we implement a parameter then we can play with it easier and get a sense for an optional one - perhaps we can even think of a way to determine the "best" length given the lines we have.

As is my habit for silly things like this, I just coded away until it worked. Not much design planning, and it is possible there are corner cases I did not consider that won't be easy to shoehorn in etc. But the basics are there I think. If we could simply transfer all those GMT_Message lines to a single string, e.g.,

	GMT_Message (API, GMT_TIME_NONE, "\t<grid> is file to be modified.\n");
	GMT_Message (API, GMT_TIME_NONE, "\n\tOPTIONS:\n");
	GMT_Message (API, GMT_TIME_NONE, "\t-A Adjust dx/dy to be compatible with the file domain or -R.\n");
	GMT_Message (API, GMT_TIME_NONE, "\t-C Remove the command history from the header.\n");

to

"\n\tOPTIONS:\n"
	"\t-A Adjust dx/dy to be compatible with the file domain or -R.\n"
	"\t-C Remove the command history from the header.\n"

and then call GMT_Wrap_Message (API, GMT_TIME_NONE, msg);

@KristofKoch
Copy link
Contributor

Not exactly helping but I still can't get testbreak to run. My apologies.

@PaulWessel
Copy link
Member Author

Looks like I forgot to give the magic information that you must enable this in your cmake/ConfigUserAdvanced.cmake:

set (DO_API_TESTS ON)

otherwise it does not compile all the test*.c codes that only developers care about. Sorry about that.

@maxrjones
Copy link
Member

maxrjones commented Mar 7, 2021

Not exactly helping but I still can't get testbreak to run. My apologies.

Also, after building this branch you can add it to your PATH like this (assuming your build directory is named build):

export PATH='<path-to-gmt-repo>/build/src/':$PATH

where <path-to-gmt-repo> needs to be changed to the appropriate path

@KristofKoch
Copy link
Contributor

Ahhhh, with the magic information I got it to work. Thanks, @PaulWessel. And thank you @meghanrjones for the reminder.

Unfortunately it doesn't break cleanly after 80 chars for me:

testbreak-80

@PaulWessel
Copy link
Member Author

True, it was written with the count as "guidance" and break on the next nearest opportunity. Breaking at exactly 80 means in the middle of arguments which I think is an affront to all human decency...

@KristofKoch
Copy link
Contributor

The terminal window in the screenshot above is 80 chars wide. My understanding was that I give the terminal width and therefore the count acts as limit and not as guidance. Maybe break < 77 for the variant and < 79 for the variant (to allow for the extra chars)? Basically the last opportunity to break prior to reaching the count?

@PaulWessel
Copy link
Member Author

I can probably change the code to keep track of the last break point and when we exceed the count go there.

@KristofKoch
Copy link
Contributor

@PaulWessel do you see a chance for the deluxe version? Get the current size of the terminal window and break accordingly? I'm not a C-programmer but maybe https://stackoverflow.com/questions/1022957/getting-terminal-width-in-c#1022961 is a starting point?

If feasible this would end the discussion between the 80x24 supporters and the "I have a monster display and I want to use it" crowd as well without resorting to a fixed break count at build time or as a variable.

@PaulWessel
Copy link
Member Author

We could try. First will need to see if @joa-quim can try the simple code in the link you provided and see if it even works for Window. It worked fine in macOS.

@PaulWessel
Copy link
Member Author

While the ISO code for the fancy return did not work for @joa-quim, I would be astonished if there is not some other glyph that Windows has that we could pick if on Windows.

@PaulWessel
Copy link
Member Author

OK, I think we want those extra lines as they clearly makes it easier to see the paragraphs. I have update the code for the common options and the three modules gmtsimplify, plot, and basemap.

@KristofKoch
Copy link
Contributor

Nice, @PaulWessel! I really like it. While reading through the reformatted plot output I got another idea on how to improve readability: Bold text to visually separate commands from text. Both you and I use some kind of text styling on GitHub and in the Forum to indicate what is a command and what is regular text. Why not in the shell as well?

Bold text

Try for yourself:
printf "\e[m\nAlternatively, append c<period>[/<phase>] for custom cyclicity.\n\nAlternatively, append \e[1mc<period>[/<phase>] \e[mfor custom cyclicity.\e[m\n\n"

I don't know about Windows. Maybe @joa-quim can paste printf "\e[mnormal text \e[1mbold text\e[m\n" into a terminal and see if he gets something like

normal and bold text

And yes, I smell feature creep. It has nothing to do with "Explore how to break synopsis lines". Your thoughts?

Copy link
Contributor

@KristofKoch KristofKoch left a comment

Choose a reason for hiding this comment

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

Really happy with the new layout!

@PaulWessel
Copy link
Member Author

Hi @KristofKoch. @meghanrjones and I decided that even if we started now it would take some time to implement this new scheme across all modules without seriously delaying GMT 6.2.0. So I think we will continue work on this branch but not let is stop us from releasing 6.2.0. We sill start with RC1 soon but probably after our community meeting on Thursday. Thus. we can continue to experiment with bold/italics styles - it is an interesting suggestion and I guess there are escape sequences to do the switcharoo. Your examples above did not do anything for me though (macOS), so this depends on other things than UTF-8.

@maxrjones
Copy link
Member

Hi @KristofKoch. @meghanrjones and I decided that even if we started now it would take some time to implement this new scheme across all modules without seriously delaying GMT 6.2.0. So I think we will continue work on this branch but not let is stop us from releasing 6.2.0.

I agree

@KristofKoch
Copy link
Contributor

I agree not to delay 6.2 for this, @PaulWessel and @meghanrjones.

The bold font doesn't work for you @PaulWessel? I'm on MacOS as well and it works for me in the default Terminal.app and in my usually used iTerm.app.

Terminal.app
terminal_app

iTerm.app
term_app

@PaulWessel
Copy link
Member Author

Turns out it does not work when your Terminal's font was set to Courier Bold...
If I select another non-bold font then it works.

@PaulWessel
Copy link
Member Author

We will merge this into master and prioritize updating the 150 modules for 6.3. All comment options have been updated already. I just now replaced OPTIONS: with OPTIONAL ARGUMENTS and added REQUIRED ARGUMENTS to the three modules I have worked on. Please have a final check - one question: I think we may want to change the indentation of the ...ARGUMENTS line since it is using a tab which is no longer used by the others. Perhaps 2 spaces will work here?

@maxrjones
Copy link
Member

We will merge this into master and prioritize updating the 150 modules for 6.3. All comment options have been updated already. I just now replaced OPTIONS: with OPTIONAL ARGUMENTS and added REQUIRED ARGUMENTS to the three modules I have worked on. Please have a final check - one question: I think we may want to change the indentation of the ...ARGUMENTS line since it is using a tab which is no longer used by the others. Perhaps 2 spaces will work here?

Yes, I agree that it would look better aligned evenly with either 'usage' or the arguments, but not indented further than everything else.

@PaulWessel
Copy link
Member Author

OK, done, will wait for internal tests to give green light, then merge.

@PaulWessel PaulWessel changed the title WIP Explore how to break synopsis lines Improve usage documentation and break synopsis lines to fit terminal Jun 16, 2021
@maxrjones maxrjones merged commit 5ddd715 into master Jun 16, 2021
@maxrjones maxrjones deleted the test-break branch June 16, 2021 21:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants