How to prevent Mathematica from inserting random line breaks in usage messages?
I faced the same problem when writing my own package (a general relativity toolkit for Mathematica). I solved it, sort of, by using the following module to define usage messages:
CreateUsageMessage[f_, args_List, msg_String, additional_List : {}] := (
Evaluate[f::usage] = StringReplace["\!\(\*RowBox[{\"" <> ToString[f] <> "\", \"[\", StyleBox[\"" <> StringRiffle[args, ","] <> "\", \"TI\"], \"]\"}]\) " <> StringReplace[msg, MapIndexed["`" <> ToString[#2[[1]]] <> "`" -> "\!\(\*StyleBox[\"" <> #1 <> "\", \"TI\"]\)" &, ToString /@ Join[args, additional]]], {" " -> "\[NonBreakingSpace]"}];
);
Attributes[UsageMessage] = HoldAll;
It automatically converts spaces to \[NonBreakingSpace]
so that the usage message doesn't break in weird places. As a bonus, it also displays the arguments in a nicely formatted way, as in the built-in usage messages.
For example:
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:
Unfortunately this causes another problem, where lines must break in the middle of words, because they cannot break on the non-breaking spaces... But it still looks much better than breaking the sentence in random places that have nothing to do with the window width. I think this is something that Wolfram really needs to fix in future versions of Mathematica.
EDIT: I tried to incorporate Carl Woll's answer into my module. However, I could not find any way to print out a StandardForm
string while still having the arguments in italics. It seems like the two are mutually exclusive. Any advice would be appreciated.
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