8
$\begingroup$

I am writing a Mathematica package, and documenting its functions with ::usage messages. However, when I type ?FunctionName to view the usage message of a function, Mathematica inserts seemingly random line breaks into the message.

Here is an example (I replaced the letters in the message with x's, because the actual text of the message doesn't matter):

test::usage = 
  "xxxxxxxxxxxxxxxxxxxxxx[xxxxxxxx, xxxxxxxxx, xxxxx] xxx x xxxxxxxxxxxxxxx xxxx xxx xxx xxxxxxxxxxx xxxxx xxxxxxxxxxxx x xxxx xxxxxx xxxxxxx xx xxx xxxxxxxxx xxxxxxx xxxxxxxxxxx xxx xxx xxxxxx xxxxxxx.";
?test

The output in Mathematica is as follows:

enter image description here

For some reason, Mathematica chooses to add a line break in the middle of the sentence, which was not there before, instead of using the entire line width. As a result, the output looks ugly - especially since the first line is significantly shorter than the second line.

Is there any way to avoid this?

$\endgroup$
4
  • 1
    $\begingroup$ Well, there's certainly a way: replace all the spaces with \[NonBreakingSpace]. But this is bad and I hope there's a better answer. $\endgroup$ Feb 6 at 19:39
  • 1
    $\begingroup$ @PatrickStevens: Thanks, this works, but seems a bit extreme... People have been writing Mathematica packages for decades, am I really the first person to encounter this issue? :O $\endgroup$
    – Wolf
    Feb 6 at 20:47
  • $\begingroup$ @Bill: Thanks, I tired this but it doesn't seem to change anything. $\endgroup$
    – Wolf
    Feb 6 at 20:48
  • $\begingroup$ You can always put your own line breaks (\n) in the string where you want them as well. It's obviously not always what you want, but it's easy to do at least. $\endgroup$ Feb 10 at 22:01
4
$\begingroup$

I faced the same problem when writing my own package (OGRe: An Object-Oriented General Relativity Package). My initial solution, which I first posted here, was to convert spaces to \[NonBreakingSpace], which stopped Mathematica from breaking the lines in weird places - but also forced it to break in the middle of words...

Then I found another solution, using a dirty trick where I converted English letters to characters from the Mathematical Alphanumeric Symbols Unicode block, which are inherently bold and/or italic. But that wasn't a good solution either.

However, Carl Woll, in the comments to my answer, suggested a perfect solution combining his answer and my old answer. My new code for a module that generates a nicely-formatted usage message is as follows:

CreateUsageMessage[f_, args_List, msg_String] := (
    Evaluate[f::usage] = ToString[TextCell[Row[{
        ToString[f],
        "[",
        Splice[(Style[#, Bold] &)/@ Riffle[args, ", "]],
        "] ",
        Splice[StringSplit[msg, "`"] /. (ToString[#] -> Style[args[[#]], Bold] & /@ Range[1, Length[args]])]
        }]],
        StandardForm
    ];
);
Attributes[UsageMessage] = HoldAll;

I prefer bold for the arguments, but if you want italic, simply replace Bold with Italic.

Here is an example of using this module:

CreateUsageMessage[TList, {ID, indices, coordinatesID}, "lists the unique, non-zero components of the tensor object `1` with the index configuration `2` and in the coordinate system `3`.
`2` should be a list of the form {\[PlusMinus]1, \[PlusMinus]1, ...}, where +1 corresponds to an upper index and -1 corresponds to a lower index.
If the index configuration and/or coordinate system are omitted, the default ones will be used."];

This will produce the following usage message:

enter image description here

Problem solved! Thanks Carl!

$\endgroup$
4
  • $\begingroup$ You can just use something like Row[{Style["f", Bold], "[", Style["arg", Italic], "] is xxx"}] to get bold and italic letters. $\endgroup$
    – Carl Woll
    Apr 14 at 15:50
  • $\begingroup$ I tried that, and got an error saying that the usage message must be a string. This is exactly why I had to use this dirty trick in the first place. $\endgroup$ Apr 14 at 21:34
  • $\begingroup$ I'm talking about the argument of TextCell, which is inside of ToString. $\endgroup$
    – Carl Woll
    Apr 15 at 0:09
  • $\begingroup$ Ah, I see what you mean now. Thanks, that works perfectly! Please see my new edit :) $\endgroup$ Apr 15 at 14:11
5
$\begingroup$

I usually discourage the use of StandardForm strings, but this is a case where it makes sense, since usage messages have to be strings. The key is to format the string as a text cell using TextCell, since these strings line-break as text. Using a simple string instead formats as an expression. So:

test::usage = ToString[
    TextCell["xxxxxxxxxxxxxxxxxxxxxx[xxxxxxxx, xxxxxxxxx, xxxxx] xxx x xxxxxxxxxxxxxxx xxxx xxx xxx xxxxxxxxxxx xxxxx xxxxxxxxxxxx x xxxx xxxxxx xxxxxxx xx xxx xxxxxxxxx xxxxxxx xxxxxxxxxxx xxx xxx xxxxxx xxxxxxx."],
    StandardForm
];

Then:

?test

enter image description here

$\endgroup$
2
  • $\begingroup$ +1. It seems to work as well with TraditionalForm as StandardForm, but perhaps there's a drawback this example does not show? $\endgroup$
    – Michael E2
    Feb 10 at 22:54
  • 1
    $\begingroup$ This did the trick, thanks. But why do you usually discourage the use of StandardForm strings? And are there any issues that may arise from using StandardForm in my usage messages? $\endgroup$
    – Wolf
    Feb 11 at 2:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.